新聞中心
環(huán)境:springboot2.3.9.RELEASE

懷柔網(wǎng)站建設(shè)公司成都創(chuàng)新互聯(lián)公司,懷柔網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為懷柔上1000家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\外貿(mào)營(yíng)銷(xiāo)網(wǎng)站建設(shè)要多少錢(qián),請(qǐng)找那個(gè)售后服務(wù)好的懷柔做網(wǎng)站的公司定做!
Spring提供兩種編程式事務(wù)管理方法:
- 使用TransactionTemplate 或 TransactionalOperator
- 直接創(chuàng)建TransactionManager的實(shí)現(xiàn)
Spring官方推薦使用TransactionTemplate方式
準(zhǔn)備
- // 實(shí)體類(lèi)
- @Entity
- @Table(name = "BC_USERS")
- @Data
- public class Users{
- private String username ;
- private String password ;
- private Integer status = 0 ;
- }
- // DAO
- public interface UsersRepository extends JpaRepository
{ - @Modifying
- @Query("update Users u set u.status=?1,u.password='123123' where u.id=?2")
- int updateUsers(Integer status, String id) ;
- }
- @Mapper
- public interface UsersMapper {
- int insertUser(Users user) ;
- }
- // Mapper.xml
- insert into bc_users (id, username, password) values (#{id}, #{username}, #{password})
1 TransactionTemplate
1.1 有返回值的
- @Service
- public class UserService {
- @Resource
- private TransactionTemplate transactionTemplate ;
- @Resource
- private UsersRepository usersRepository ;
- public Integer saveUsers(Users users) {
- this.transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
- Integer result = transactionTemplate.execute(new TransactionCallback
() { - @Override
- public Integer doInTransaction(TransactionStatus status) {
- return usersMapper.insertUser(users) ;
- }
- }) ;
- return result ;
- }
- }
1.2 無(wú)返回值的
當(dāng)沒(méi)有返回值時(shí)可以使用
TransactionCallbackWithoutResult
- public void saveUsers(Users users) {
- transactionTemplate.execute(new TransactionCallbackWithoutResult() {
- @Override
- protected void doInTransactionWithoutResult(TransactionStatus status) {
- usersMapper.insertUser(users) ;
- }
- }) ;
- }
1.3 事務(wù)回滾
事務(wù)的回滾通過(guò)
TransactionStatus.setRollbackOnly方法
- public Users saveUser(Users users) {
- return transactionTemplate.execute(new TransactionCallback
() { - @Override
- public Users doInTransaction(TransactionStatus status) {
- try {
- return usersMapper.insertUser(users) ;
- } catch (Exception e) {
- status.setRollbackOnly() ;
- }
- return null ;
- }
- }) ;
- }
1.4 配置事務(wù)屬性
在實(shí)例化TransactionTemplate對(duì)象的時(shí)候我們可以對(duì)事務(wù)進(jìn)行相關(guān)的屬性配置,通過(guò)如下方式。
- private TransactionTemplate transactionTemplate ;
- public UserService(PlatformTransactionManager transactionManager) {
- this.transactionTemplate = new TransactionTemplate(transactionManager) ;
- this.transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED);
- this.transactionTemplate.setTimeout(30); //seconds
- }
測(cè)試代碼
- public Integer updateUsers(Integer statusValue, String id) {
- return transactionTemplate.execute(new TransactionCallback
() { - @Override
- public Integer doInTransaction(TransactionStatus status) {
- return usersRepository.updateUsers(statusValue, id) ;
- }
- }) ;
- }
- @Modifying
- @Query("update Users u set u.status=?1 where u.id=?2")
- int updateUsers(Integer status, String id) ;
由于這里事務(wù)傳播屬性設(shè)置的NOT_SUPPORTED.所以程序會(huì)報(bào)錯(cuò)誤
- org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query
- at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:403)
- at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:257)
- at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:531)
2 TransactionalOperator
TransactionalOperator適用于反應(yīng)式編程,這里不做介紹。
3 TransactionManager
使用TransactionManager管理事務(wù)也有兩種
PlatformTransactionManager,
ReactiveTransactionManager
ReactiveTransactionManager適用于反應(yīng)式編程,這里不做介紹。
3.1 PlatformTransactionManager
在程序中可以使用
PlatformTransactionManager來(lái)控制事務(wù)的提交與回滾
示例:
- private PlatformTransactionManager transactionManager ;
- private DefaultTransactionDefinition definition ;
- private TransactionStatus status ;
- @Resource
- private UsersRepository usersRepository ;
- public UserService3(PlatformTransactionManager transactionManager) {
- this.transactionManager = transactionManager ;
- definition = new DefaultTransactionDefinition() ;
- definition.setName("pgName") ;
- definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED) ;
- }
- public Integer saveUsers(Users users) {
- TransactionStatus status = this.transactionManager.getTransaction(definition) ;
- Integer result = null ;
- try {
- result = usersMapper.insertUser(users) ;
- } catch (Exception e) {
- transactionManager.rollback(status) ;
- throw e ;
- }
- transactionManager.commit(status) ;
- publisher.publishEvent(new UsersEvent(users));
- return result ;
- }
4 事務(wù)事件監(jiān)聽(tīng)
通過(guò)@
TransactionalEventListener注解監(jiān)聽(tīng)事務(wù)的不同階段的事件信息
- public @interface TransactionalEventListener {
- TransactionPhase phase() default TransactionPhase.AFTER_COMMIT;
- boolean fallbackExecution() default false;
- @AliasFor(annotation = EventListener.class, attribute = "classes")
- Class>[] value() default {};
- @AliasFor(annotation = EventListener.class, attribute = "classes")
- Class>[] classes() default {};
- String condition() default "";
- }
fallbackExecution: 默認(rèn)值false;如果設(shè)置為true,當(dāng)前即便沒(méi)有事務(wù)也會(huì)觸發(fā)事件。
TransactionPhase:默認(rèn)值是事務(wù)提交以后;有如下幾個(gè)取值:
- public enum TransactionPhase {
- BEFORE_COMMIT, // 事務(wù)提交前觸發(fā)
- AFTER_COMMIT, // 事務(wù)提交后觸發(fā)
- AFTER_ROLLBACK, // 事務(wù)回滾觸發(fā)
- AFTER_COMPLETION // 事務(wù)完成后 觸發(fā)
- }
注意:@
TransactionalEventListener注解只對(duì)聲明式事務(wù)起作用,對(duì)編程式事務(wù)無(wú)效。僅適用于由PlatformTransactionManager管理的線程綁定事務(wù)
示例:
- // 事件監(jiān)聽(tīng)
- @Component
- public class TxListenerComponent {
- @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
- public void handleUsersAfterCommit(UsersEvent usersEvent) {
- Users user = (Users) usersEvent.getSource() ;
- System.out.println("AfterCommit收到事件通知:" + user.getPassword()) ;
- }
- @TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION)
- public void handleUsersAfterCompletion(UsersEvent usersEvent) {
- Users user = (Users) usersEvent.getSource() ;
- System.out.println("AfterCompletion收到事件通知:" + user.getPassword()) ;
- }
- @TransactionalEventListener(phase = TransactionPhase.AFTER_ROLLBACK)
- public void handleUsersAfterRollback(UsersEvent usersEvent) {
- Users user = (Users) usersEvent.getSource() ;
- System.out.println("AfterRollback收到事件通知:" + user.getPassword()) ;
- }
- @TransactionalEventListener(phase = TransactionPhase.BEFORE_COMMIT)
- public void handleUsersBeforeCommit(UsersEvent usersEvent) {
- Users user = (Users) usersEvent.getSource() ;
- System.out.println("BeforeCommit收到事件通知:" + user.getPassword()) ;
- }
- }
- // 發(fā)布事件
- @Resource
- private ApplicationEventPublisher publisher ;
- @Resource
- private UsersMapper usersMapper ;
- public Integer saveUsers(Users users) {
- Integer result = transactionTemplate.execute(new TransactionCallback
() { - @Override
- public Integer doInTransaction(TransactionStatus status) {
- return usersMapper.insertUser(users) ;
- }
- }) ;
- publisher.publishEvent(new UsersEvent(users));
- return result ;
- }
運(yùn)行結(jié)果:
- 2021-06-17 14:02:56.830 DEBUG 10000 --- [nio-8081-exec-1] com.pack.mapper.UsersMapper.insertUser : ==> Preparing: insert into bc_users (id, username, password) values (?, ?, ?)
- 2021-06-17 14:02:56.840 DEBUG 10000 --- [nio-8081-exec-1] com.pack.mapper.UsersMapper.insertUser : ==> Parameters: mmmmm(String), mmmmm(String), mmmmm(String)
- 2021-06-17 14:02:56.842 DEBUG 10000 --- [nio-8081-exec-1] com.pack.mapper.UsersMapper.insertUser : <== Updates: 1
- BeforeCommit收到事件通知:mmmmm
- AfterCommit收到事件通知:mmmmm
- AfterCompletion收到事件通知:mmmmm
總結(jié):編程式的事務(wù)適合少量的事務(wù)操作;比如在一個(gè)服務(wù)的調(diào)用中有大量的計(jì)算操作,最后將計(jì)算結(jié)果進(jìn)行事務(wù)的操作這種情況就適合應(yīng)用事務(wù)編程式的進(jìn)行事務(wù)控制。如果一個(gè)操作有很多的事務(wù)的操作那聲明式的事務(wù)方式就更加的合適。
網(wǎng)頁(yè)名稱(chēng):Springboot編程式事務(wù)使用方式詳解
URL分享:http://m.fisionsoft.com.cn/article/cohoiii.html


咨詢(xún)
建站咨詢(xún)
