您的位置:首页 > 编程语言 > Java开发

spring配置事务之注解方式

2013-09-01 14:36 357 查看
具体步骤如下:

jdbc事务管理,使用注解的方式步骤如下
* 引入命名空间
* xmlns:context="http://www.springframework.org/schema/context" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd

* xmlns:aop="http://www.springframework.org/schema/aop" http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
--事务的命名空间
* xmlns:tx="http://www.springframework.org/schema/tx" http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd

* 在beans.xml文件中增加如下配置
<!--1 增加spring的自动扫描功能 -->
<context:component-scan base-package="cn.itcast" />

<!-- 2 配置dbcp连接池 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
<!--配置初始化连接数 -->
<property name="initialSize" value="5"/>
<!-- 配置最大连接数 -->
<property name="maxActive" value="20"/>
<!-- 配置最大空闲数 防止洪峰退去时,连接池中连接数过多-->
<property name="maxIdle" value="10"/>
<!-- 配置最小空闲数 防止洪峰到来时,连接池中连接池中连接的数量过少,引起的性能开销-->
<property name="minIdle" value="5"/>
<!--设置最大等待时间,如果超过这个时间,连接池将抛出异常-->
<property name="maxWait" value="5000"/>
<property name="defaultAutoCommit" value="true"/>
</bean>

<!--3 配置jdbcTemplate -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>

<!--4 配置jdbc的事务管理器 Aop的切面-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入数据源 -->
<property name="dataSource" ref="dataSource" />
</bean>

<!-- 5 配置事务级别的注解使用的事务管理器 -->
<tx:annotation-driven transaction-manager="txManager"/>
* 处理dao层
* 处理存款的dao层
* 创建InAccountDaoImpl对象 使用@Repository注解
@Repository("accountDao")
public class InAccountDaoImpl implements InAccountDao

* 注入jdbcTemplate到该dao层
@Resource(name="jdbcTemplate")
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
* 处理账户的dao层
* 创建AccountDaoImpl对象 使用@Repository注解
@Repository("accountDao")
public class AccountDaoImpl implements AccountDao

* 注入jdbcTemplate到该dao层
@Resource(name="jdbcTemplate")
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}

* 处理业务层
* 创建业务层的对象
@Service("inAccountService")
public class InAccountServiceImpl implements InAccountService

* 注入dao层的对象
@Resource(name="inAccountDao")
private InAccountDao inAccountDao;

@Resource(name="accountDao")
private AccountDao accountDao;
* 处理事务
* 定义类级别的事务(设置事务是只读的)
@Transactional(readOnly=true)
@Service("inAccountService")
public class InAccountServiceImpl implements InAccountService

* 定义方法级别的事务
@Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.DEFAULT,readOnly=false)
public void saveInAccount(InAccount inAccount)

注:方法级别的事务会覆盖类级别的事务

* 测试

创建两张表:

#账户表
create table account
(
accountid varchar(18) primary key, #账号id
balance double(10,2) #余额
)

#存款表
create table inaccount
(
accountid varchar(18),
inbalance double(10,2) #存入金额
)

#存款
# 插入存款的数据到inaccount表
# 查询该账号对应的余额 --account表查
# 计算新的账号余额
# 更新账号余额(以账号为id更新account表的balance)

Domain:
Account

public class Account {
private String accountid;

private Double balance;

public String getAccountid() {
return accountid;
}

public void setAccountid(String accountid) {
this.accountid = accountid;
}

public Double getBalance() {
return balance;
}

public void setBalance(Double balance) {
this.balance = balance;
}

}
InAccount
public class InAccount {
private String accountid;
private Double inbalance;

public String getAccountid() {
return accountid;
}

public void setAccountid(String accountid) {
this.accountid = accountid;
}

public Double getInbalance() {
return inbalance;
}

public void setInbalance(Double inbalance) {
this.inbalance = inbalance;
}
}

Dao层:

AccountDao

public interface AccountDao {
public Account findAccountById(String accountid);

public void updateAccount(Account account);

}
InAccountDao
public interface InAccountDao {
public void saveInAccount(InAccount inAccount);
}

Dao实现层:

AccountDaoImpl

@Repository("accountDao")
public class AccountDaoImpl implements AccountDao {
//注入JdbcTemplate,默认按名称,找不到名称按类型,也可以直接设置名称,但是设置了名称若名称找不到不能回退到类型查找
@Resource
private JdbcTemplate jdbcTemplate;

public Account findAccountById(String accountid) {
String sql="SELECT accountid,balance FROM account WHERE accountid=?";
Object[] args={accountid};
Account account=(Account)this.getJdbcTemplate().queryForObject(sql, args, new RowMapper(){
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
Account account=new Account();
account.setAccountid(rs.getString(1));
account.setBalance(rs.getDouble(2));
return account;
}
});
return account;
}
/**
* 更新账号余额
*/
public void updateAccount(Account account) {
try{
//组织sql语句
String sql="UPDATE account SET balance=? WHERE accountid=?";
Object[] args={account.getBalance(),account.getAccountid()};
int[] argTypes={java.sql.Types.DOUBLE,java.sql.Types.VARCHAR};
//该方法抛出运行时异常
this.getJdbcTemplate().update(sql, args, argTypes);
}catch(Exception e){
e.printStackTrace();
throw new RuntimeException(e);
}
}

public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}

@Resource(name="jdbcTemplate")
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
}

InAccountDaoImpl

@Repository("inAccountDao")
public class InAccountDaoImpl implements InAccountDao {
@Resource
private JdbcTemplate jdbcTemplate;

/**
* 保存信息到存款表中
*/
public void saveInAccount(InAccount inAccount) {
String sql="INSERT INTO inaccount (accountid, inbalance) VALUES(?,?)";
Object[] args={inAccount.getAccountid(),inAccount.getInbalance()};
int[] argTypes={java.sql.Types.VARCHAR,java.sql.Types.DOUBLE};
this.getJdbcTemplate().update(sql, args, argTypes);
}

public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}

@Resource(name="jdbcTemplate")
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
}

Service层:

InAccountService

public interface InAccountService {
public void saveInAccount(InAccount inAccount);
}
Service实现层:
InAccountServiceImpl

@Transactional(readOnly=true)
@Service("inAccountService")
public class InAccountServiceImpl implements InAccountService {
@Resource
private InAccountDao inAccountDao;
@Resource
private AccountDao accountDao;

@Transactional(readOnly=false,propagation=Propagation.REQUIRED,isolation=Isolation.DEFAULT)
public void saveInAccount(InAccount inAccount) {

// 1* 插入存款的数据到inaccount表
inAccountDao.saveInAccount(inAccount);
// 2* 查询该账号对应的余额 --account表查
Account account = accountDao.findAccountById(inAccount.getAccountid());

// 3* 计算新的账号余额
Double balance = account.getBalance() + inAccount.getInbalance();

account.setBalance(balance);

// 4* 更新账号余额(以账号为id更新account表的balance)
accountDao.updateAccount(account);

}

public InAccountDao getInAccountDao() {
return inAccountDao;
}

public void setInAccountDao(InAccountDao inAccountDao) {
this.inAccountDao = inAccountDao;
}

public AccountDao getAccountDao() {
return accountDao;
}

public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
}

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<!-- 1增加spring的自动扫描功能 -->
<context:component-scan base-package="com.xxc"/>

<!-- 2.配置DBCP数据源 -->
<bean id="dbcpDataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
<!-- 配置初始化连接数 -->
<property name="initialSize" value="5"/>
<!-- 配置最大连接数 -->
<property name="maxActive" value="20"/>
<!-- 配置最大空闲数,防止洪峰退去时,连接池中连接数过多 -->
<property name="maxIdle" value="10"/>
<!-- 配置最小空闲数,防止洪峰到来时,连接池中连接数过少-->
<property name="minIdle" value="5"/>
<!-- 设置最大等待事件,如果超过这个时间,连接池将抛出异常,例如:最大连接数是20个,当21个连接来的时候就需要等待-->
<property name="maxWait" value="5000"/>
</bean>

<!-- 配置jdbcTemplate -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dbcpDataSource"/>
</bean>

<!--4 配置jdbc的事务管理器 Aop的切面-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dbcpDataSource"/>
</bean>

<!-- 5 配置事务级别的注解使用的事务管理器,注解有可能在方法上(通知上) 可以理解为配置通知在哪个切面上-->
<tx:annotation-driven transaction-manager="txManager"/>

</beans>


测试:

public class App {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("com/xxc/applicationContext.xml");

//<bean id="inAccountService" class="cn.itcast.service.impl.InAccountServiceImpl">
InAccountService inAccountService=(InAccountService)ac.getBean("inAccountService");

//存款
InAccount inAccount=new InAccount();
inAccount.setAccountid("1");
inAccount.setInbalance(5d);
inAccountService.saveInAccount(inAccount);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: