程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 詳解Java的MyBatis框架中的事務處置

詳解Java的MyBatis框架中的事務處置

編輯:關於JAVA

詳解Java的MyBatis框架中的事務處置。本站提示廣大學習愛好者:(詳解Java的MyBatis框架中的事務處置)文章只能為提供參考,不一定能成為您想要的結果。以下是詳解Java的MyBatis框架中的事務處置正文


1、MyBatis零丁應用時,應用SqlSession來處置事務:

public class MyBatisTxTest { 
 
  private static SqlSessionFactory sqlSessionFactory; 
  private static Reader reader; 
 
  @BeforeClass 
  public static void setUpBeforeClass() throws Exception { 
    try { 
      reader = Resources.getResourceAsReader("Configuration.xml"); 
      sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); 
    } finally { 
      if (reader != null) { 
        reader.close(); 
      } 
    } 
  } 
   
  @Test 
  public void updateUserTxTest() { 
    SqlSession session = sqlSessionFactory.openSession(false); // 翻開會話,事務開端 
     
    try { 
      IUserMapper mapper = session.getMapper(IUserMapper.class); 
      User user = new User(9, "Test transaction"); 
      int affectedCount = mapper.updateUser(user); // 因前面的異常而未履行commit語句 
      User user = new User(10, "Test transaction continuously"); 
      int affectedCount2 = mapper.updateUser(user2); // 因前面的異常而未履行commit語句 
      int i = 2 / 0; // 觸發運轉時異常 
      session.commit(); // 提交會話,即事務提交 
    } finally { 
      session.close(); // 封閉會話,釋放資本 
    } 
  } 
} 


2、和Spring集成後,應用Spring的事務治理:
一個應用MyBatis-Spring的重要緣由是它許可MyBatis介入到Spring的事務治理中。而不是給MyBatis創立一個新的特定的事務治理器,MyBatis-Spring應用了存在於Spring中的DataSourceTransactionManager。
一旦DataSourceTransactionManager設置裝備擺設好了,你可以在Spring中以你平日的做法來設置裝備擺設事務。@Transactional注解和AOP款式的設置裝備擺設都是支撐的。在事務處置時代,一個零丁的SqlSession對象將會被創立和應用。當事務完成時,這個session會以適合的方法提交或回滾。
一旦事務創立以後,MyBatis-Spring將會通明的治理事務。在你的DAO或Service類中就不須要額定的代碼了。

1.尺度設置裝備擺設
要開啟Spring的事務處置,在Spring的XML設置裝備擺設文件中簡略創立一個DataSourceTransactionManager對象:

<bean id="transactionManager" class="org.springframework.jdbc.datasource 
  .DataSourceTransactionManager"> 
  <property name="dataSource" ref="dataSource"/> 
</bean> 

指定的DataSource普通可所以你應用Spring的隨意率性JDBC DataSource。這包括了銜接池和經由過程JNDI查找取得的DataSource。
要留意,為事務治理器指定的DataSource必需和用來創立SqlSessionFactoryBean的是統一個數據源,不然事務治理器就沒法任務了。
 
2.容器治理事務
假如你正應用一個JEE容器並且想讓Spring介入到容器治理事務中,那末Spring應當應用JtaTransactionManager或它的容器指定的子類來設置裝備擺設。做這件工作的最便利的方法是用Spring的事務定名空間:

<tx:jta-transaction-manager/> 

在這類設置裝備擺設中,MyBatis將會和其它由容器治理事務設置裝備擺設的Spring事務資本一樣。Spring會主動應用隨意率性存在的容器事務,在下面附加一個SqlSession。 假如沒有開端事務,或許須要基於事務設置裝備擺設,Spring會開啟一個新的容器治理事務。
留意,假如你想應用容器治理事務,而不想應用Spring的事務治理,你就必需設置裝備擺設SqlSessionFactoryBean來應用根本的MyBatis的ManagedTransactionFactory而不是其它隨意率性的Spring事務治理器: 

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> 
  <property name="dataSource" ref="dataSource"/> 
  <property name="transactionFactoryClass"> 
    <value>org.apache.ibatis.transaction.managed.ManagedTransactionFactory"/> 
  </property> 
</bean> 

 
3.編程式事務治理
MyBatis的SqlSession供給指定的辦法來處置編程式的事務。然則當應用MyBatis-Spring時,bean將會應用Spring治理的SqlSession或映照器來注入。那就是說Spring平日是處置事務的。你不克不及在Spring治理的SqlSession上挪用SqlSession.commit(),SqlSession.rollback()或SqlSession.close()辦法。假如如許做了,就會拋出UnsupportedOperationException異常。留意在應用注入的映照器時不克不及拜訪那些辦法。不管銜接能否設置為主動提交,SqlSession數據辦法的履行或在Spring事務以外隨意率性挪用映照器辦法都將會主動被提交。上面是一個編程式事務示例:

DefaultTransactionDefinition def = new DefaultTransactionDefinition(); 
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); 
TransactionStatus status = txManager.getTransaction(def); 
try{ 
  userMapper.insertUser(user); 
}catch(MyException ex){ 
  throw ex; 
} 
txManager.commit(status); 

4.@Transactional方法:

在類途徑下創立beans-da-tx.xml文件,在beans-da.xml(系列五)的基本上參加事務設置裝備擺設:

<!-- 事務治理器 --> 
<bean id="txManager" 
  class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
    <property name="dataSource" ref="dataSource" /> 
</bean> 
 
<!-- 事務注解驅動,標注@Transactional的類和辦法將具有事務性 --> 
<tx:annotation-driven transaction-manager="txManager" /> 
 
<bean id="userService" class="com.john.hbatis.service.UserService" /> 

辦事類:

@Service("userService") 
public class UserService { 
 
  @Autowired 
  IUserMapper mapper; 
 
  public int batchUpdateUsersWhenException() { // 非事務性 
    User user = new User(9, "Before exception"); 
    int affectedCount = mapper.updateUser(user); // 履行勝利 
    User user2 = new User(10, "After exception"); 
    int i = 1 / 0; // 拋出運轉時異常 
    int affectedCount2 = mapper.updateUser(user2); // 未履行 
    if (affectedCount == 1 && affectedCount2 == 1) { 
      return 1; 
    } 
    return 0; 
  } 
 
  @Transactional 
  public int txUpdateUsersWhenException() { // 事務性 
    User user = new User(9, "Before exception"); 
    int affectedCount = mapper.updateUser(user); // 因前面的異常而回滾 
    User user2 = new User(10, "After exception"); 
    int i = 1 / 0; // 拋出運轉時異常,事務回滾 
    int affectedCount2 = mapper.updateUser(user2); // 未履行 
    if (affectedCount == 1 && affectedCount2 == 1) { 
      return 1; 
    } 
    return 0; 
  } 
} 

在測試類中參加:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = { "classpath:beans-da-tx.xml" }) 
public class SpringIntegrateTxTest { 
 
  @Resource 
  UserService userService; 
 
  @Test 
  public void updateUsersExceptionTest() { 
    userService.batchUpdateUsersWhenException(); 
  } 
 
  @Test 
  public void txUpdateUsersExceptionTest() { 
    userService.txUpdateUsersWhenException(); 
  } 
} 


5.TransactionTemplate方法

在beans-da-tx.xml中添加:

<bean id="txTemplate" class="org.springframework.transaction.support.TransactionTemplate"> 
  <constructor-arg type="org.springframework.transaction.PlatformTransactionManager" ref="transactionManager" /> 
</bean> 

在UserService類參加:

@Autowired(required = false) 
TransactionTemplate txTemplate; 
 
public int txUpdateUsersWhenExceptionViaTxTemplate() { 
  int retVal = txTemplate.execute(new TransactionCallback<Integer>() { 
 
    @Override 
    public Integer doInTransaction(TransactionStatus status) { // 事務操作 
      User user = new User(9, "Before exception"); 
      int affectedCount = mapper.updateUser(user); // 因前面的異常而回滾 
      User user2 = new User(10, "After exception"); 
      int i = 1 / 0; // 拋出運轉時異常並回滾 
      int affectedCount2 = mapper.updateUser(user2); // 未履行 
      if (affectedCount == 1 && affectedCount2 == 1) { 
        return 1; 
      } 
      return 0; 
    } 
     
  }); 
  return retVal; 
} 

在SpringIntegrateTxTest類中參加:

@Test 
public void updateUsersWhenExceptionViaTxTemplateTest() { 
  userService.txUpdateUsersWhenExceptionViaTxTemplate(); //  
} 

注:弗成catch Exception或RuntimeException而不拋出:

@Transactional 
public int txUpdateUsersWhenExceptionAndCatch() { // 事務性操作,然則核心框架捕捉不到異常,以為履行准確而提交。 
  try { 
    User user = new User(9, "Before exception"); 
    int affectedCount = mapper.updateUser(user); // 履行勝利 
    User user2 = new User(10, "After exception"); 
    int i = 1 / 0; // 拋出運轉時異常 
    int affectedCount2 = mapper.updateUser(user2); // 未履行 
    if (affectedCount == 1 && affectedCount2 == 1) { 
      return 1; 
    } 
  } catch (Exception e) { // 一切異常被捕捉而未拋出 
    e.printStackTrace(); 
  } 
  return 0; 
} 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved