Spring --16.Spring基於註解的宣告事務控制
阿新 • • 發佈:2018-11-19
1、建立子工程、引入依賴 (同上xml方式)
2、編寫相關類、(同上xml方式)
3、開啟Spring對註解的支援、配置事務管理、開啟Spring對註解的支援
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:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--開啟事務註解的支援 transaction-manager;寫事務管理器的id--> <tx:annotation-driven transaction-manager="transactionManager"/> <!--開啟Spring註解掃描--> <context:component-scan base-package="com.day04_tx_anno"></context:component-scan> <!--匯入jdbc--> <context:property-placeholder location="classpath:jdbc.properties"/> <!--採用註解一定要用JdbcTemplate.因為在dao中要注入JdbcTemplate--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${jdbc.driverClass}"></property> <property name="url" value="${jdbc.url}"></property> <property name="username" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password}"></property> </bean> <!--配置事務管理器--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!--注入資料來源--> <property name="dataSource" ref="dataSource"></property> </bean> </beans>
4、在相關類上加註解
AccountDaoImpl.java
package com.day04_tx_anno.dao.Impl; import com.day04_tx.dao.AccountDao; import com.day04_tx.domain.Account; import com.day04_tx.rowmapper.AccountRowMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.support.JdbcDaoSupport; import org.springframework.stereotype.Repository; /** * * @ Author :ShaoWei Sun. * @ Date :Created in 9:38 2018/11/15 */ @Repository("accountDao") public class AccountDaoImpl implements AccountDao { @Autowired private JdbcTemplate jdbcTemplate; /** * 根據id查詢使用者物件 * @param id * @return */ @Override public Account findById(Long id) { Account account = jdbcTemplate.queryForObject("select * from account where id = ?", new AccountRowMapper(), id); return account; } /** * 更新使用者物件 * @param account */ @Override public void update(Account account) { jdbcTemplate.update("update account set name = ?, money = ? where id =? ",account.getName(),account.getMoney(),account.getId()); } }
AccountServiceImpl.java
package com.day04_tx_anno.service.Imlp; import com.day04_tx.dao.AccountDao; import com.day04_tx.domain.Account; import com.day04_tx.service.AccountService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; /** * @ Author :ShaoWei Sun. * @ Date :Created in 9:53 2018/11/15 */ @Service("accountService") @Transactional//該類中所有的方法都加可讀寫的事務 public class AccountServiceImpl implements AccountService { @Autowired private AccountDao accountDao; @Override public void transfer(Long fromId, Long toId, Double money) { //查詢轉出賬戶 Account fromAccount = accountDao.findById(fromId); //查詢轉入帳戶 Account toAccount = accountDao.findById(toId); //轉出帳戶撿錢 fromAccount.setMoney(fromAccount.getMoney()-money); //轉入帳戶加錢 toAccount.setMoney(toAccount.getMoney()+money); //更新轉出賬戶 accountDao.update(fromAccount); //int i = 1/0; //更新轉入賬戶 accountDao.update(toAccount); } /** * 查詢功能、現在做了修改操作、但不允許的。 * @param id 使用者id * @return */ @Override public Account findById(Long id) { Account account = accountDao.findById(id); account.setMoney(100000d); accountDao.update(account); return account; } }
5、在業務層中find開頭的方法加只讀事務@Transactional(readOnly=true)
AccountServiceImpl.java
package com.day04_tx_anno.service.Imlp;
import com.day04_tx.dao.AccountDao;
import com.day04_tx.domain.Account;
import com.day04_tx.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* @ Author :ShaoWei Sun.
* @ Date :Created in 9:53 2018/11/15
*/
@Service("accountService")
@Transactional//該類中所有的方法都加可讀寫的事務
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountDao accountDao;
@Override
public void transfer(Long fromId, Long toId, Double money) {
//查詢轉出賬戶
Account fromAccount = accountDao.findById(fromId);
//查詢轉入帳戶
Account toAccount = accountDao.findById(toId);
//轉出帳戶撿錢
fromAccount.setMoney(fromAccount.getMoney()-money);
//轉入帳戶加錢
toAccount.setMoney(toAccount.getMoney()+money);
//更新轉出賬戶
accountDao.update(fromAccount);
//int i = 1/0;
//更新轉入賬戶
accountDao.update(toAccount);
}
/**
* 查詢功能、現在做了修改操作、但不允許的。
* @param id 使用者id
* @return
*/
@Override
@Transactional(readOnly = true)//只讀事務
public Account findById(Long id) {
Account account = accountDao.findById(id);
account.setMoney(100000d);
accountDao.update(account);
return account;
}
}
提示:@Transactional註解也可以加在方法上,如果類上和方法上都有@Transactional,則以方法上的為準。
測試註解事務是否成功
執行單元測試類TestTx中的test1方法,控制檯報“被零除”異常,account表中的資料也沒有發生變化,表示註解事務配置成功啦!
執行Test2方法、發現會出現
注:實際開發中。事務只用xml配置、註解牽涉到第三方類就不能用了。