SpringMVC事務ロールバック機構
Spring事物では、Springによってデータベースのデータ接続を管理しています.@Transactionはpublic方法に適用するだけで有効です.コメントを取得する時、AbstractFallbackTransation SourceのcomputterTransation Attribute方法を呼び出します.
Springがthrow new RuntimeExceptionに捕獲された時、物事が戻ってきます.
物事の方法にtry catchを入れると、Springが異常を捕まえられなくなり、データを転がすことができなくなります.データは正常に保存されていて、ロールバックできません.
以上が現在理解されているSpringのロールバックメカニズムです.問題があればお互いに勉強することができます.
private TransactionAttribute computeTransactionAttribute(Method method, Class> targetClass) {
// Don't allow no-public methods as required.
// public
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
return null;
}
//
}
この方法は、ターゲットメソッドの修飾子がpublicであるかどうかを確認します.publicでないと、@Transationの属性情報を取得できません.最終的にはTransaction Intercepterにこの目標方法をブロックさせて事務管理をさせない.Springがthrow new RuntimeExceptionに捕獲された時、物事が戻ってきます.
@Transactional
public void insertRole(RoleBean roleBean) {
roleDao.insertRole(roleBean);
throw new RuntimeException();
}
Springがthrow new Exceptionに捕獲された場合、物事は戻りません.(下記のコードはコンパイルできません.説明だけです.)
@Transactional
public void insertRole(RoleBean roleBean) {
roleDao.insertRole(roleBean);
throw new Exception();
}
この時Exceptionの異常を捕獲するには、注釈@Transactiol(rollbackFor=Exception.class)が必要です.複数であれば、rollbackFor={Exception.class、Exceptions.class}ができます.
@Transactional(rollbackFor=Exception.class)
public void insertRole(RoleBean roleBean) {
roleDao.insertRole(roleBean);
throw new Exception();
}
Spring aop 異常捕獲原理:ブロックされた方法は明示的に異常を投げなければならず、自分でtry catchを行うことができません.このようにaopエージェントは方法の異常を捕まえて、ロールバックを行うことができます.デフォルトではaopはthrow new RuntimeExceptionの異常だけを捕獲します.物事の方法にtry catchを入れると、Springが異常を捕まえられなくなり、データを転がすことができなくなります.データは正常に保存されていて、ロールバックできません.
@Transactional
public void insertRole(RoleBean roleBean) {
try {
roleDao.insertRole(roleBean);
throw new RuntimeException();
} catch (Exception e) {
e.printStackTrace();
}
}
したがって、cathcの後に方法を加えれば、二つのdelete方法に物事を加えなくても、成功することができます.(Spring事物はデフォルトでは、方法運行時に、一つのものがあったら、このものに加入して、さもなくば新しいものを作成します.insertRoleは事務をプラスしたので、その内にroleDao.insertRole()小包されることがあります.最後の2行のdeleteRoleId 1とdeleteRoleId 2も同じ事務管理の下で、deleteRoleId 1は事務管理をすると表示されますが、伝播レベルは特に明記されていませんので、デフォルトの事務伝播行為(propagation=Propgation.REQUID)したがって、deleteRoleId 1は、トランザクションの注釈がある場合、外部の方法insertRoleは、新しい事務を自分で建てます.しかし、insertRoleはすでに事務があります.ですから、deleteRoleId 1はinsertRoleの事務に参加します.自分のものを使うことはありません.)
@Transactional
public void insertRole(RoleBean roleBean) {
try {
roleDao.insertRole(roleBean);
throw new RuntimeException();
} catch (Exception e) {
e.printStackTrace();
}
deleteRoleId1(roleId);
deleteRoleId2(roleId);
}
@Transactional
public void deleteRoleId1(Integer roleId) {
roleDao.deleteRoleId(roleId);
}
public void deleteRoleId2(Integer roleId) {
roleDao.deleteRoleId(roleId);
}
だからSpringで物事を戻したいなら、自分で物事を捕獲したり、捕獲したりしないでください.catchの中で一つの間違いを投げたら、Springは物事が逆戻りします.
@Transactional
public void insertRole(RoleBean roleBean) {
try {
roleDao.insertRole(roleBean);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException();
}
}
@Transactional
public void insertRole(RoleBean roleBean) {
if (roleBean != null) {
roleDao.insertRole(roleBean);
}else{
throw new RuntimeException();
}
}
insertRoleに事務がない場合、DeleteRoleIdを呼び出し、DeleteRoleId方法に異常がない場合でも、Spring事務はデータをロールバックすることができません.Spring事務はAOPダイナミックエージェントですので、自分で自分の方法を呼び出して、代理対象を生成しません.AOPがありません.これはSpring事務の自動呼び出しが無効になったということです.(insertRole方法に@Transactional事務の注釈を加えると、データはロールバックし、前の文の事務の伝播を参照する)
public void insertRole(RoleBean roleBean) {
deleteTerminalByRoleId(3);
}
@Transactional
public void deleteRoleId(int roleId) {
roleDao.deleteRoleId(roleId);
throw new RuntimeException();
}
以上が現在理解されているSpringのロールバックメカニズムです.問題があればお互いに勉強することができます.