この記事の主な研究は、次のように、春のトランザクション分離レベルの紹介と例です。
同じデータベースのレコードで2つのトランザクションが動作する場合、それらの間の影響は何ですか?これにより、トランザクション分離レベルの概念が生まれます。データベースの分離は、同時実行制御と多くの関係があります。データベースの分離レベルは、データベースのトランザクション特性の酸の一部です。酸、つまり、原子性、一貫性、分離、耐久性。 Springには、 READ_UNCOMMITTED 、 READ_COMMITTED 、 REPEATABLE_READ 、 SERIALIZABLE 4つのトランザクション分離レベルがあります。もう1つは、データベースのDEFAULTのデフォルトの分離レベルであり、MySQLはDefaultにREPEATABLE_READになります。
以下で詳細に見てみましょう。
名前が示すように、 READ_UNCOMMITTED 、あるトランザクションが別のトランザクションがコミットしていないトランザクションレコードを読み取ることができることを意味します。言い換えれば、トランザクションは、他のトランザクションによってまだコミットされていないデータを読み取ることができます。これは、スプリングトランザクションの最も弱い分離レベルです。以下の図を参照してください。トランザクションAがオンになり、レコードが記録されています。この時点で、トランザクションBはデータを読み取り、このレコードを読み取りますが、トランザクションAはロールバックします。したがって、トランザクションBで読み取られるデータは無効です(データベースは無効な状態です)。この状況はDirty Readと呼ばれます。 Dirty Readingの問題に加えて、 READ_UNCOMMITTEDは、 non-repeatable read (繰り返し読み取りではない)およびphantom read (Phantom Reading)もある場合があります。
READ_COMMITTED分離レベルは、トランザクションがコミットされたレコードのみを読み取ることができ、コミットされていないレコードを読み取れないことを示しています。言い換えれば、トランザクションはコミットされたデータのみを読み取ることができ、コミットされていないデータを読み取ることができません。したがって、汚い読み取り状況はもはや発生しませんが、他の問題が発生する可能性があります。下の写真を参照してください。
トランザクションAの2つの読み取りの間で、トランザクションBはその記録とコミットを修正します。したがって、トランザクションAの前後に読まれたレコードは一貫性がありません。この問題は、非回復可能な読み取りと呼ばれます(繰り返し読むことはできません)。 (レコードは2回の間で一貫して読まれ、繰り返し読みを繰り返すと問題が発生します。)
繰り返しのない読み取りの問題に加えて、 READ_COMMITTEDはPhantom読み取りの問題もある場合があります。
Repeatible_Readとは、トランザクションがデータベースからレコードを複数回読み取ることができ、レコードが複数回読み取ることが同じであることを意味します。この分離レベルは、汚い読み取りと非回復不可能な読み取りの問題を回避できますが、Phantom読み取りの問題が発生する可能性があります。下の図に示すように。
トランザクションAは、データベースから一連のレコードを2回読み取ります。その間、トランザクションBはレコードを挿入して送信します。トランザクションAが2回目に読み取ると、トランザクションBが挿入されたばかりのレコードが読み取られます。トランザクション中に、トランザクションA 2回で読まれた一連のレコードは一貫性がなく、この問題はPhantom Readと呼ばれます。
Serializableは、Springの最強の分離レベルです。トランザクションが実行されると、トランザクションが一緒に起こるのではなく、シリアル方法で実行されるかのように、読み取りと書き込みのように、すべてのレベルでロックされます。これにより、汚い読み取り、非回復可能な読み取り、ファントムの読み取りが防止されますが、パフォーマンスの劣化を引き起こします。
mysqlはREPEATABLE_READにデフォルトです。
以下の例を見てみましょう。データベースMySQLでトランザクションを開き、コミットしません。次に、別のトランザクションがレコードを読み取ります。
最初は、図に示されているように、データベースのレコードが
次に、データベースMySQLでトランザクションAを開き、レコードを挿入します。
サービス内のサービスクラスのトランザクション属性は、 READ_UNCOMMITTEDとして構成されています。
@TransActionAl(ISOLATION = ISOLATION.READ_UNCOMMITTED)public class AccountService {private Accountdao accountdao; public countdao;} public void setaccountdao(accountdao accountdao){this.accuntdao = councountdao;} countdao;} countdao;} {accountdao.outmoney(from、money); accountdao.inmoney(to、money);} public void readalluser(){list <counce> account> accounts = counceddao.getalluser(); for(account:accounts){system.out.println(account);}}}}}}}}次のテストクラスを実行します
パッケージcom.chris.service; import static org.junit.assert。*; import org.junit.test; import org.junit.runner.runwith; import org.springframework.beans.annotation.autowired; import org.context.context.context.context.context.context.context.context.context.context.context.context.context.context.context.context.context.context.context.context.contex springframework.context.junit4.springjunit4classrunner; @runwith(springjunit4classrunner.class)@contextconfiguration( "ClassPath:ApplicationContext.xml")Public Class readallusertest {@autowired caustsservice accountservice; {accountservice.readalluser();}}結果は次のとおりです。
このトランザクションは、コミットされていないデータを読み取ることがわかります。
この時点で、MySQLでオープンしたトランザクションAをロールバックします。
mysql> lollback;
プログラムをもう一度実行すると、結果は次のとおりです
account [name = michael、money = 1000.0]
account [name = jane、money = 1000.0]
account [name = kate、money = 1000.0]
上記は、Springトランザクションの分離レベルの紹介と例の分析に関するこの記事のすべての内容です。私はそれが誰にでも役立つことを願っています。興味のある友人は、このサイトの他の関連トピックを引き続き参照できます。欠点がある場合は、それを指摘するためにメッセージを残してください。このサイトへのご支援をありがとうございました!