Beginning Spring学习笔记——第6章(三)使用Spring进行编程式事务管理
来源:互联网 发布:js实现中奖后彩带特效 编辑:程序博客网 时间:2024/06/05 14:21
这样的方式对于一个庞大的方法可以将其中一部分事务化,定义事务开始和结束的位置。
使用Transaction Template进行编程式事务管理
这是Spring推荐使用的方法。
首先向AccountServiceImpl类中添加一个TransactionTemplate属性及其setter方法,然后在tansfertMoney方法中调用TransactionTemplate.execute方法,以TransactionCallbackWithoutResult类创建的匿名类为输入参数。
public class AccountServiceImpl implements AccountService { private AccountDao accountDao; private TransactionTemplate transactionTemplate; public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } public void setTransactionTemplate(TransactionTemplate transactionTemplate) { this.transactionTemplate = transactionTemplate; } @Override public void transferMoney(final long sourceAccountId, final long targetAccountId, final double amount) { transactionTemplate.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus status) { Account sourceAccount = accountDao.find(sourceAccountId); Account targetAccount = accountDao.find(targetAccountId); sourceAccount.setBalance(sourceAccount.getBalance() - amount); targetAccount.setBalance(targetAccount.getBalance() + amount); accountDao.update(sourceAccount); accountDao.update(targetAccount); } }); }}
然后在Configuration类中通过将transactionManager注入其构造函数来定义transactionTemplate Bean。tansactionManager和dataSource Bean定义不变。并将tansactionTemplate Bean注入accountService Bean中。
@Configuration@Import(Ch4Configuration.class)public class Ch6Configuration { @Bean public TransactionTemplate transactionTemplate() { TransactionTemplate transactionTemplate = new TransactionTemplate(); transactionTemplate.setTransactionManager(transactionManager()); return transactionTemplate; } @Bean public DataSource dataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("org.h2.Driver"); dataSource.setUrl("jdbc:h2:tcp://localhost/~/test"); dataSource.setUsername("sa"); dataSource.setPassword(""); return dataSource; } @Bean public PlatformTransactionManager transactionManager() { DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(); transactionManager.setDataSource(dataSource()); return transactionManager; } @Bean @Autowired public AccountService accountService(AccountDao accountDao) { AccountServiceImpl bean = new AccountServiceImpl(); bean.setAccountDao(accountDao); bean.setTransactionTemplate(transactionTemplate()); return bean; }}
然后就可以在Main类中测试新的实现了。
public class Main { public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext( Ch6Configuration.class); AccountService accountService = applicationContext.getBean(AccountService.class); accountService.transferMoney(100L, 101L, 5.0d); }}
执行前ACCOUNT表的内容:
执行后:
转账成功!
使用PlatformTransactionManager API进行编程式事务管理
这是一种低级的方法,与JDBC API管理事务边界类似。
首先向AccountServiceImpl类中添加一个PlatformTransactionManagerAPI属性及其setter方法。用该PlatformTransactionManager创建新的TransactionDefinition对象以便获取TransactionStatus。用AccountDao方法完成数据访问操作,顺利则通过transactionManager.commit(status)提交事务,否则使用transactionManager.rollback(status)确定是否回滚。
public class AccountServiceImpl implements AccountService { private AccountDao accountDao; private PlatformTransactionManager transactionManager; public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } public void setTransactionManager(PlatformTransactionManager transactionManager) { this.transactionManager = transactionManager; } @Override public void transferMoney(long sourceAccountId, long targetAccountId, double amount) { TransactionDefinition definition = new DefaultTransactionDefinition(); TransactionStatus status = transactionManager.getTransaction(definition); try { Account sourceAccount = accountDao.find(sourceAccountId); Account targetAccount = accountDao.find(targetAccountId); sourceAccount.setBalance(sourceAccount.getBalance() - amount); targetAccount.setBalance(targetAccount.getBalance() + amount); accountDao.update(sourceAccount); accountDao.update(targetAccount); transactionManager.commit(status); } catch (Exception e) { transactionManager.rollback(status); throw new RuntimeException(e); } }}
在配置类中将transactionManager注入accountService Bean中。
@Configuration@Import(Ch4Configuration.class)public class Ch6Configuration { @Bean public DataSource dataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("org.h2.Driver"); dataSource.setUrl("jdbc:h2:tcp://localhost/~/test"); dataSource.setUsername("sa"); dataSource.setPassword(""); return dataSource; } @Bean public PlatformTransactionManager transactionManager() { DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(); transactionManager.setDataSource(dataSource()); return transactionManager; } @Bean @Autowired public AccountService accountService(AccountDao accountDao) { AccountServiceImpl bean = new AccountServiceImpl(); bean.setAccountDao(accountDao); bean.setTransactionManager(transactionManager()); return bean; }}
然后就可以运行Main函数测试新的实现了。
public class Main { public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext( Ch6Configuration.class); AccountService accountService = applicationContext.getBean(AccountService.class); accountService.transferMoney(101L, 100L, 5.0d); }}
运行前ACCOUNT表如上图,运行后:
转账成功!
在事务执行前后执行自定义逻辑
通知事务性操作
将事务功能作为一个AOP通知,使用Spring AOP功能进行处理。
可使用MethodInceptor拦截方法调用,在调用前后执行一些额外操作。并在XML文件中的aop:config元素中使用aop:advisor定义在哪些方法上触发该逻辑。
使用TransactionSynchronization执行事务后逻辑
使用回调机制指定当前事务结束时需要执行的自定义代码块。TransactionSynchronization接口定义为:
public interface TransactionSynchronization extends Flushable{ int STATUS_COMMITED = 0; int STATUS_ROLLED_BACK = 1; int STATUS_UNKNOWN = 2; void beforeCommit(boolean readOnly); void afterCommit(); void afterCompletion(int status);}
提交事务前调用befroeCommit方法,但不确定调用方法后会提交当前事务。该方法中抛出的任何异常都会传递给调用这。
- Beginning Spring学习笔记——第6章(三)使用Spring进行编程式事务管理
- Beginning Spring学习笔记——第6章(二)使用Spring进行声明式事务管理
- Beginning Spring学习笔记——第6章(一)Spring事务管理基础
- Spring备忘——事务管理(编程式事务管理)
- 使用Spring(16)使用TransactionTemplate进行Spring编程式事务管理
- Beginning Spring学习笔记——第7章 使用Spring进行测试驱动开发
- Spring学习8-Spring事务管理(编程式事务管理)
- spring 编程式事务管理—PlatformTransactionManager
- spring 编程式事务管理—PlatformTransactionManager
- Beginning Spring学习笔记——第2章(三)Spring的Bean管理
- SPRING 编程式事务管理
- Spring编程式事务管理
- Spring编程式事务管理
- spring编程式事务管理
- spring编程式事务管理
- spring 编程式事务管理
- Spring 编程式事务管理
- Spring编程式事务管理
- Java抽象类和接口的区别
- css用margin :0 auto 后依旧无法对齐
- Beginning Spring学习笔记——第6章(二)使用Spring进行声明式事务管理
- Kaggle:数据践行者的好去处(如何开展大数据的实践?)
- Replace Words
- Beginning Spring学习笔记——第6章(三)使用Spring进行编程式事务管理
- eclipse下载插件速度很慢解决方案
- Array Nesting
- 程序员的八重境界
- 如何理解keras中的shape/input_shape
- keras中的层layer
- Java集合(一)-List与ArrayList(扩容与装箱和取消装箱)
- Java中Vector,ArrayList和LinkedList的区别
- [Nodejs] Debug-Ternimal