トランザクションとは、一連の N 段階のデータベース操作から構成される論理的な実行単位であり、この一連の操作はすべて実行されるか、すべて中止されます。
トランザクションの特性ACID
:
原子性: トランザクションはアプリケーション内で分割できません 最小限の実行body
整合性: トランザクションの実行の結果、データはある整合性状態から別の整合性状態に変更される必要があります
分離永続性: 実行各トランザクションは互いに干渉せず、トランザクションの内部操作は他のトランザクションから分離されます
永続性: トランザクションが送信されると、データへの変更はすべて記録される必要があります。永続ストレージ
一般的な同時実行例外
最初のタイプの更新の喪失、2 番目のタイプの更新の喪失更新の喪失
#ダーティ リード、非反復読み取り、ファントム リード
#Repeatable Read: 反復可能な読み取り
Serializable: Serialization
最初のタイプの更新損失: トランザクションのロールバックにより、別のトランザクションに更新データが失われます。
ダーティ リード: 特定のトランザクションが別のトランザクションからコミットされていないデータを読み取ります。
反復不可能な読み取り: 特定のトランザクションが前後で同じデータを読み取る結果は一貫性がありません。
ファントム読み取り: 特定のトランザクションで、同じテーブルの前後でクエリされた行数が不一致です。
分離レベルダーティ リード | 2 番目のタイプの失われた更新 | 繰り返し不可能な読み取り | ファントム読み取り | ##コミットされていない読み取り | |
---|---|---|---|---|---|
Yes | Yes | Yes | ##コミット済みの読み取り | No | |
はい | ##はい#はい | 繰り返し読み取り | ##No | ##NoNo | No |
Repeatable Read | No | No | No | No | |
4. トランザクション管理 | 実装メカニズム | 悲観的ロック (データベース) |
オプティミスティック ロック (カスタム)
バージョン番号、タイムスタンプなど
更新前データを取得する際は、バージョン番号が変更されているかどうかを確認してください。変更が発生した場合は、この更新をキャンセルします。それ以外の場合は、データを更新します (バージョン番号 1)
XML 構成を通じてメソッドのトランザクション特性を宣言します。
アノテーションを使用してメソッドのトランザクション特性を宣言します。
プログラムによるトランザクション
package com.nowcoder.community.service; import com.nowcoder.community.dao.AlphaDao; import com.nowcoder.community.dao.DiscussPostMapper; import com.nowcoder.community.dao.UserMapper; import com.nowcoder.community.entity.DiscussPost; import com.nowcoder.community.entity.User; import com.nowcoder.community.util.CommunityUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.support.TransactionCallback; import org.springframework.transaction.support.TransactionTemplate; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import java.util.Date; @Service //@Scope("prototype") public class AlphaService { @Autowired private AlphaDao alphaDao; @Autowired private UserMapper userMapper; @Autowired private DiscussPostMapper discussPostMapper; @Autowired private TransactionTemplate transactionTemplate; public AlphaService() { // System.out.println("实例化AlphaService"); } @PostConstruct public void init() { // System.out.println("初始化AlphaService"); } @PreDestroy public void destroy() { // System.out.println("销毁AlphaService"); } public String find() { return alphaDao.select(); } // REQUIRED: 支持当前事务(外部事务),如果不存在则创建新事务. // REQUIRES_NEW: 创建一个新事务,并且暂停当前事务(外部事务). // NESTED: 如果当前存在事务(外部事务),则嵌套在该事务中执行(独立的提交和回滚),否则就会REQUIRED一样. @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED) public Object save1() { // 新增用户 User user = new User(); user.setUsername("alpha"); user.setSalt(CommunityUtil.generateUUID().substring(0, 5)); user.setPassword(CommunityUtil.md5("123" + user.getSalt())); user.setEmail("alpha@qq.com"); user.setHeaderUrl("https://cache.yisu.com/upload/information/20220823/112/6198.png"); user.setCreateTime(new Date()); userMapper.insertUser(user); // 新增帖子 DiscussPost post = new DiscussPost(); post.setUserId(user.getId()); post.setTitle("Hello"); post.setContent("新人报道!"); post.setCreateTime(new Date()); discussPostMapper.insertDiscussPost(post); Integer.valueOf("abc"); return "ok"; } public Object save2() { transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED); transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); return transactionTemplate.execute(new TransactionCallback<Object>() { @Override public Object doInTransaction(TransactionStatus status) { // 新增用户 User user = new User(); user.setUsername("beta"); user.setSalt(CommunityUtil.generateUUID().substring(0, 5)); user.setPassword(CommunityUtil.md5("123" + user.getSalt())); user.setEmail("beta@qq.com"); user.setHeaderUrl("https://cache.yisu.com/upload/information/20220823/112/6199.png"); user.setCreateTime(new Date()); userMapper.insertUser(user); // 新增帖子 DiscussPost post = new DiscussPost(); post.setUserId(user.getId()); post.setTitle("你好"); post.setContent("我是新人!"); post.setCreateTime(new Date()); discussPostMapper.insertDiscussPost(post); Integer.valueOf("abc"); return "ok"; } }); } }
以上がSpringBootトランザクション管理例の分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。