(1),事務隔離級别
事務隔離級别
(1) 隻讀事務 readOnly 隻讀資料, 不更新資料
(2) 必須其他事務寫完了,才能讀取
isolation=Isolation.READ_COMMITTED , 資料庫預設事務隔離級别
(3) 可重複讀 REPEATABLE_READ
一,在讀的時候加行鎖
二,第一次讀取後,此行資料就不能被其他事務寫,
為了對讀取值進行檢驗,再次讀取。
兩次讀取結果相同
三,不可避免幻讀
(4) Serializable
一,讀鎖寫鎖互斥, 可以避免 不可重複讀, 幻讀,
髒讀: 讀取未送出的資料, 解決方案加事務
不可重複讀, 幻讀 差別
1,不可重複讀重點在于 update 和 delete
2,幻讀重點在于 insert
二,極大的降低資料庫并發能力
(2),事務傳播行為
事務傳播行為
(1) Propagation.REQUIRED
一,支援目前事務, 如果沒有事務就建立一個事務
二,如果存在事務就會加入目前事務
(2) Propagation.REQUIRES_NEW
一,目前方法必須啟動新事務, 并在它自己的事務内運作
二,如果有其他事務正在運作, 應該将它挂起
三,外層事務不會影響内部事務的送出復原
四,内部事務的異常則會影響外部事務
(3),範例-部分代碼
<!--配置-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://127.0.0.1:3306/grcdb05?useUnicode=true&characterEncoding=utf8" />
<property name="username" value="root" />
<property name="password" value="root" />
<property name="defaultAutoCommit" value="false" />
</bean>
<!-- spring和MyBatis整合,不需要mybatis的配置映射檔案 -->
<!-- 自動掃描mapping.xml檔案 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="/WEB-INF/mybatis/mybatis-config.xml"></property>
</bean>
<!-- SqlSessionTemplate 對象可以使用 SqlSessionFactory 作為構造方法的參數來建立 -->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
/**
* @auther: xiongbl
* @date: 2022/11/27 12:13
* @desc: 測試學生類服務層
*/
@Service
public class StudentService {
@Autowired
private SqlSessionTemplate sqlSession;
@Transactional(propagation = Propagation.REQUIRES_NEW
, isolation = Isolation.REPEATABLE_READ
, timeout = 1000
, rollbackFor = RuntimeException.class)
public void updateA() throws RuntimeException {
String sqlState = "select count(1) age_count from t00_user where age > 18 ";
Integer age_count = sqlSession.selectOne("com.entity.commonDao.queryInteger", sqlState);
if(age_count > 0) {
System.out.println("年齡大于18歲的學生,才能工作");
}
}
}