Java?Spring的兩種事務你知道嗎
1. Spring中的事務控制方式
Spring的事務控制可以分為編程式事務控制和聲明式事務控制。
編程式
開發(fā)者直接把事務的代碼和業(yè)務代碼耦合到一起,在實際開發(fā)中不用。
聲明式
開發(fā)者采用配置的方式來實現的事務控制,業(yè)務代碼與事務代碼實現解耦合,使用的AOP思想。
2.編程式事務控制相關對象
2.1PlatformTransactionManager
PlatformTransactionManager接口,是spring的事務管理器接口,里面提供了我們常用的操作事務的方法。


2.2TransactionDefinition
TransactionDefinition接口提供事務的定義信息(事務隔離級別、事務傳播行為等等)

(1)事務隔離級別
設置隔離級別,可以解決事務并發(fā)產生的問題,如臟讀、不可重復讀和虛讀(幻讀)。
注意:使用數據庫默認級別,如果數據庫是mysql,則默認是可重復讀,oracle是讀已提交。
ISOLATION_DEFAULT 使用數據庫默認級別
ISOLATION_READ_UNCOMMITTED 讀未提交
ISOLATION_READ_COMMITTED 讀已提交(可解決臟讀問題)
ISOLATION_REPEATABLE_READ 可重復讀 (可解決臟讀、不可重復讀)
ISOLATION_SERIALIZABLE 串行化
可解決:

(2)事務傳播行為
事務傳播行為指的就是當一個業(yè)務方法【被】另一個業(yè)務方法調用時,應該如何進行事務控制。

重點:

read-only(是否只讀):建議查詢時設置為只讀timeout(超時時間):默認值是-1,沒有超時限制。如果有,以秒為單位進行設置
2.3 TransactionStatus
TransactionStatus 接口提供的是事務具體的運行狀態(tài)。

可以簡單的理解三者的關系:事務管理器通過讀取事務定義參數進行事務管理,然后會產生一系列的事務狀態(tài)。
Spring中的事務控制主要就是通過這三個API實現的
PlatformTransactionManager 負責事務的管理,它是個接口,其子類負責具體工作
TransactionDefinition 定義了事務的一些相關參數
TransactionStatus 代表事務運行的一個實時狀態(tài)
理解三者的關系:事務管理器通過讀取事務定義參數進行事務管理,然后會產生一系列的事務狀態(tài)。
3.基于XML的聲明式事務控制【重點】
在Spring配置文件中聲明式的處理事務來代替代碼式的處理事務。底層采用AOP思想來實現。
聲明式事務控制明確事項:
核心業(yè)務代碼(目標對象) (切入點是誰?)
事務增強代碼(Spring已提供事務管理器))(通知是誰?)
切面配置(切面如何配置?)(切面 = 切入點 + 通知)
3.1快速入門
使用spring聲明式事務控制轉賬業(yè)務。
步驟:
1.引入tx命名空間
2.事務管理器通知配置
3.事務管理器AOP配置
4.測試事務控制轉賬業(yè)務代碼
(1)引入tx命名空間
<?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
">
(2)事務管理器通知配置
<!--事務管理器對象-->
<!--<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>-->
// 通知增強
<tx:advice id="txAdvice" transaction-manager="transactionManager">
//定義事務的一些屬性 * 表示當前任意名稱的方法都走默認配置
<!--
name: 切點方法名稱
isolation:事務的隔離級別
propagation:事務的傳播行為
read-only:是否只讀
timeout:超時時間
-->
<tx:attributes>
<tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" timeout="-1"/>
//CRUD常用配置
<tx:method name="save*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="find*" read-only="true"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
(3)事務管理器AOP配置
當使用spring聲明式管理事務,要使用aop:advisor來進行aop的配置!
//aop配置:配置切面
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.lagou.servlet.impl.AccountServiceImpl.*(..))"/>
</aop:config>-->
事務參數的配置詳解:
<tx:method name=“transfer” isolation=“REPEATABLE_READ” propagation=“REQUIRED”timeout="-1" read-only=“false”/>
name:切點方法名稱isolation:事務的隔離級別propogation:事務的傳播行為timeout:超時時間read-only:是否只讀
4.基于注解的聲明式事務控制(重點)
步驟:
- 修改service層,增加事務注解
- 修改spring核心配置文件,開啟事務注解支持
4.1 修改service層,增加事務注解
@Service
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountDao accountDao;
@Transactional(propagation = Propagation.REQUIRED, isolation =
Isolation.REPEATABLE_READ, timeout = -1, readOnly = false)
@Override
public void transfer(String outUser, String inUser, Double money) {
accountDao.out(outUser, money);
int i = 1 / 0;
accountDao.in(inUser, money);
}
}
4.2修改spring核心配置文件,開啟事務注解支持
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w2.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--省略之前datsSource、jdbcTemplate、組件掃描配置-->
<!--事務管理器-->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--事務的注解支持-->
<tx:annotation-driven/>
</beans
4.3純注解方式
核心配置類:
@Configuration // 聲明該類為核心配置類
@ComponentScan("com.lagou") // 包掃描
@Import(DataSourceConfig.class) //導入其他配置類
@EnableTransactionManagement //事務的注解驅動
public class SpringConfig {
@Bean
public JdbcTemplate getJdbcTemplate(@Autowired DataSource dataSource){
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
return jdbcTemplate;
}
@Bean
public PlatformTransactionManager getPlatformTransactionManager(@Autowired DataSource dataSource){
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(dataSource);
return dataSourceTransactionManager;
}
}
數據源配置類:
@PropertySource("classpath:jdbc.properties") //引入properties文件
public class DataSourceConfig {
@Value("${jdbc.driverClassName}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Bean //會把當前方法的返回值對象放進IOC容器中
public DataSource getDataSource(){
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName(driver);
druidDataSource.setUrl(url);
druidDataSource.setUsername(username);
druidDataSource.setPassword(password);
return druidDataSource;
}
}
知識小結:
- 平臺事務管理器配置(xml、注解方式)
- 事務通知的配置(@Transactional注解配置)
- 事務注解驅動的配置 <tx:annotation-driven/>、@EnableTransactionManagement
總結
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注腳本之家的更多內容!
相關文章
Spring?框架的?MethodInterceptor?簡介及示例代碼
MethodInterceptor接口定義了一個方法Object?intercept(Object?obj,?Method?method,?Object[]?args,?MethodProxy?proxy)?,該方法在代理對象的方法被調用時被觸發(fā),這篇文章主要介紹了Spring?框架的?MethodInterceptor?簡介及示例代碼,需要的朋友可以參考下2023-09-09
Java高級之HashMap中的entrySet()方法使用
這篇文章主要介紹了Java高級之HashMap中的entrySet()方法使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03

