這是HeidiSQl截圖查看不同引擎的特性: 
getTransaction定義了事務的開啟范圍,這個可以在網上找到更詳細的講解,這里不累述。commit與rollback就是基本的事務控制機制。 AbstractPlatformTransactionManager實現了該接口,這個抽象類定義一些基本的對事務支持的操作,但是抽象了不同的orm框架對事務管理的細節。jdbc是通過dataSource Connection來進行事務管理,而hibernate是通過Sqlsession進行事務管理。使用jdbc進行事務管理,就注入DataSourceTransactionManager即可。并制定對應的數據源,然后只需要制定需要代理的類即可。 數據源的配置:
<bean id="driver" class="com.mysql.jdbc.Driver"></bean> <bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource"> <property name="username" value="${username}" /> <property name="passWord" value="${password}" /> <property name="url" value="${url}" /> <property name="driver" ref="driver" /> </bean>首先我們制定事務管理器:
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean>然后我們定義需要事務傳播機制,我們來創建一個常見,也可以采用其他的方式創建advice,這里的advice通知就是定義了需要做什么,這里就是 如果有事務加入事務,沒有的話創建新事務:
<tx:advice id="advice" transaction-manager="transactionManager"> <tx:attributes> <!-- 如果有事務加入事務,沒有的話創建新事務 --> <tx:method name="*" propagation="REQUIRED" timeout="3"/> </tx:attributes> </tx:advice>做什么定義完了,就需要指定在哪里做(pointcut)即切點,代理的方式有很多種,可以使用默認的代理DefaultAdvisorAutoProxyCreator。也可以使用注解的方式,很靈活,主要就是明白定義好切點(一般spring支持較好的是方法級別的攔截)即可。這里我們使用比較方便的schema標簽支持aop代理:
<aop:config> <aop:pointcut id="txPointcut" expression="execution(* micro.test.spring.service..*Service*.*(..))" /> <aop:advisor advice-ref="advice" pointcut-ref="txPointcut"/> </aop:config>很多時候我們引入新的xml標簽會報錯,這個時候檢查xml文件頭是否引入了相關的schema即可,這點是初學者很容易犯錯的地方。
<!-- 掃描到advice --> <context:component-scan base-package="micro.test.spring" /> <!-- mybatis中sqlSession由這個類來完成 --> <bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="mapperLocations"> <list> <value>classpath:/sqlmap/ComputerMapper.xml</value> </list> </property> </bean>其他必要的配置跟本文不太相關就不貼了。 前面execution(* micro.test.spring.service..Service.*(..))就表示在這個包下面的所有方法都是切點,會被代理。這是service的一個方法,執行它:
public void testTransaction2() { Computer computer = new Computer(); computer.setBrand("test"); computerMapper.insert(computer);//事務會回滾 ComputerExample computerExample = new ComputerExample(); computerExample.or().andBrandEqualTo(computer.getBrand()); int a = 1; a /= 0; // 制造異常 computerMapper.insert(computer); }如果沒事務管理機制,會插入一條記錄。引入了事務管理機制,拋出異常(spring要求運行時異常)就不會插入記錄,因為遇到了異常,當然如果去掉異常,兩條都會插入進去,值得一提的是我數據庫設置的默認應該不是讀未提交,因為在調試到還沒拋異常的時候也不會看到一條記錄,如果是讀未提交應該是看到出現了一條記錄然后又消失了(被回滾),測試了幾次,要么有0條,要么有兩條(正常執行)。沒有造成臟讀的情況至少應該是讀已提交。查詢了一下:  果然可重復讀,是能夠不免臟讀和不可重復度兩個問題的。但是無法避免幻讀。
 果然可重復讀,是能夠不免臟讀和不可重復度兩個問題的。但是無法避免幻讀。
新聞熱點
疑難解答