序文
最近、コードをリファクタリングし、深刻なバグを見つけたとき:私は例外をキャッチする必要があるため、エラー取引法の後、でも、ロールバックされませんが、以下の具体的な理由は話します。恐怖、非常に微細な思考、プロジェクト全体は書き込みの一種です。だから、研究と@Transactionalコメントのテストを開始します。
@Transactionalは自動的にトランザクションを管理するために私たちを助けることができます。通常のサービスに加えて、注釈層のプロセスインチ しかし、ピットがたくさんあります!以下のコードは一般に擬似コードとしても知られている、型崩れコードです。
ピット:唯一の外部コールの有効
内部コール取引方法が原因でトランザクション管理のための春の動的プロキシのトランザクションは無効原因となる、外部コールは、内部コールを管理することができませんでし傍受することができます。
class UserController {
// 外部调用,受事务管理
userService.saveUser();
}
class UserService {
@Transation
public void saveUser() {}
public void saveUserInternal() {
// 内部调用,不受事务管理
saveUser();
}
}
解決策:プロキシオブジェクトを取得し、プロキシ経由でオブジェクトを呼び出すため
の最初のステップ、エージェントへのオープン暴露
<aop:aspectj-autoproxy expose-proxy="true" />
トランザクションメソッドを呼び出すためのプロキシオブジェクトを介して第二工程、
((UserService)AopContext.getProxy()).saveUser();
ピットII:publicメソッドに対してのみ有効
トランザクションの注釈が唯一の効果的な外部コール(ピットインを参照してください)ので、プライベートメソッドは、とてもプライベート無効をよく理解、内部的に呼び出すことができます。しかし、なぜ無効保護されています。stackoverflowのこの答えは私の混乱を説明します。
直接保護されたメソッドをサポートしてカット連中を、統一するためには春、その後、JDKエージェントは保護されたメソッドの傍受をサポートしていませんが、CGLIBが可能ですが、お勧めできませんこれは、次のことを意味します。
ハング3:未確認の例外にのみ有効
異常な科目や未確認の例外とは何ですか?簡単に言えば、対象が異常であるか、あなたがスローされた例外をキャッチしない場合、コンパイラは、このようなFileInputStreamのは、あなたが例外をキャッチし、または例外をスローいずれかとして、一般的な、文句を言うでしょう。
ソリューション:@Transactional(rollbackFor = Exception.class)
@Transactional(rollbackFor = Exception.class)
public void saveFile() throws FileNotFoundException {
// 数据操作
userDao.saveUser();
// 会抛出异常,因为设置了rollbackFor属性,会回滚
InputStream in = new FileInputStream(new File("xxx.xxx");
}
ハング4:スローされた例外に対してのみ有効
例外キャッチ、隠された異常の同等は、異常は自動的にロールバックされません。あなたがキャプチャしなければならない場合は、手動でコードブロックの内側にロールバックキャプチャ
@Transactional
public void saveUser() {
try {
saveUser();
} catch(Exception e) {
// 手动关闭事务
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
}
アウトスタンディング
私は、問題をデバッグする際に、取引方法、クエリを削除した後最初は正常で発生した。しかし、最初のチェックを保存した後、あなたは、保存されたデータを見つけることができません。あなたは兄、あなたは理由が低く要求することができるものを知っていれば。