2017-02-24 13 views
0

コードで遊んで、トランザクションとロールバックが春(Spring-BootとSpring-Daoを使用している)の仕組みを理解しようとします。しかし、私の満了時に私は私に説明することができない例外に直面しました。 だから私は、コントローラトランザクションのロールバック後にSpring AOPが例外を返す

@RestController 
public class OrderController { 

@Autowired 
CarSvc carSvc; 

@Autowired 
OrderService orderSvc; 

@RequestMapping(value="/administrator/order/{id}", produces = "application/json;charset=UTF-8", method = RequestMethod.PUT) 
@ResponseStatus(HttpStatus.OK) 
public Message closeOrder(@PathVariable Long id){ 
    orderSvc.closeOrder(id); 
    return new Massage("test"); 
} 

}

このコントローラ呼び出し、このサービスがあります。

@Service 
@Transactional(propagation = Propagation.REQUIRED) 
public class OrderSvc extends AbstractService implements OrderService { 

public void closeOrder(Long id) { 
    final Order order = getDAO().findOne(id); 
    Boolean isUserCanCloseOrder = order.getCarWashId().equals(getCarWashIdForAdmin()); 
    if(isUserCanCloseOrder){ 
     final Iterable<Order> all = getDAO().findAll(); 
     for(Order o : all){ 
      try { 
       orderRepo.closeOrder(o); 
      }catch (Exception e){ 
       System.out.printf("error id=" + o.getId() + " , message : " + e.getMessage()); 
      } 

     } 

    }else { 
     throw new AuthorizationException("User is not allowed to close order with id = " + id); 
    } 
} 

}

そして、tryブロックで、このサービスには、以下のリポジトリ

@Repository 
public class OrderRepo implements OrderRepository { 

@Override 
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class) 
public void closeOrder(Order order) { 
    if(order.getClose() != null){ 
     order.setUpdateVersion(77); 
    }else{ 
     order.setCarWashId(1000L + order.getId()); 
    } 
    final List<OrderedService> services = order.getServices(); 
    for(OrderedService s: services){ 
     s.setUpdateVersion(77); 
     orderedServiceDAO.save(s); 
    } 
    orderDAO.save(order); 
} 
を呼び出しを

}

ロジックは以下の通りです:リポジトリ内orderの一部Iちょうど設定のアップデート版で(私が理解する必要があるDBが更新されました)で、残りのために私は有効ではない値を持つsetCarWashId SQL例外を起動して確認していますロールバックは正常に動作します(外部キー制約によるSQL例外は失敗します)。

申し訳ありませんが、申し訳ありませんが、申し訳ありませんが、アプリケーションは正常に動作し、すべての注文を通過して、System.out.printfをサービスからすべての悪いオーダーで表示します。しかし、その後のループが終了したとき、アプリケーションは次の例外で失敗しました:

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`pitstop`.`orders`, CONSTRAINT `order_FK1` FOREIGN KEY (`car_wash_id`) REFERENCES `carwash` (`id`)) 
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_121] 
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_121] 
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_121] 
at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_121] 
at com.mysql.jdbc.Util.handleNewInstance(Util.java:404) ~[mysql-connector-java-5.1.38.jar:5.1.38] 
at com.mysql.jdbc.Util.getInstance(Util.java:387) ~[mysql-connector-java-5.1.38.jar:5.1.38] 
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:932) ~[mysql-connector-java-5.1.38.jar:5.1.38] 
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3878) ~[mysql-connector-java-5.1.38.jar:5.1.38] 
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3814) ~[mysql-connector-java-5.1.38.jar:5.1.38] 
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2478) ~[mysql-connector-java-5.1.38.jar:5.1.38] 
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2625) ~[mysql-connector-java-5.1.38.jar:5.1.38] 
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2551) ~[mysql-connector-java-5.1.38.jar:5.1.38] 
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861) ~[mysql-connector-java-5.1.38.jar:5.1.38] 
at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2073) ~[mysql-connector-java-5.1.38.jar:5.1.38] 
at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2009) ~[mysql-connector-java-5.1.38.jar:5.1.38] 
at com.mysql.jdbc.PreparedStatement.executeLargeUpdate(PreparedStatement.java:5094) ~[mysql-connector-java-5.1.38.jar:5.1.38] 
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1994) ~[mysql-connector-java-5.1.38.jar:5.1.38] 
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:208) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:62) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3281) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:3183) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3525) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:159) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:465) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:351) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:350) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:56) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1258) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:425) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:77) ~[hibernate-entitymanager-4.3.11.Final.jar:4.3.11.Final] 
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517) ~[spring-orm-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:761) ~[spring-tx-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730) ~[spring-tx-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:485) ~[spring-tx-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:291) ~[spring-tx-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) ~[spring-tx-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208) ~[spring-aop-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
at com.sun.proxy.$Proxy128.closeOrder(Unknown Source) ~[na:na] 
at biz.controllers.rest.administrator.OrderController.closeOrder(OrderController.java:52) ~[classes/:na] 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_121] 

私は間違ったFKによる例外を理解し、それが表示される理由は?私は例外のためのブロックをキャッチしている。そしてなぜログには私のコントローラ(biz.controllers.rest.administrator.OrderController.closeOrder)だけが記載されており、サービスやリポジトリへのリンクはないのですか?

私に説明してください、何が起こっているのですか? ありがとうございます。

答えて

0

私はその理由はわかりませんが、の例外OrderSvcの例外が表示されました。この注釈が削除されると、問題は消えた

0

誤ったFKが原因で例外が表示されるのはなぜですか?私は例外のためのブロックをキャッチしている。

はできるだけ早く例外が処理チェーン内のどこ表示されているとおり、春のトランザクションマネージャは、「ロールバックのトランザクションをマーク」。処理チェーンの外側の呼び出しレイヤーにキャッチブロックがある場合(コントローラー内にあるように)、要求は失敗し、トランザクション全体がロールバックされます。 OrderRepoの@Transaction定義にrollbackFor = Exception.classを指定すると、例外が発生した場合にはトランザクション全体をロールバックするようにSpringに要求します。やや似たような問題が議論されているhere on spring forum

また、スタックトレースに基づいて、Springのトランザクション処理コードの行761をに見ると、内部的に何が起こっているのかを理解することができます。そこにブレークポイントを置き、Springがトランザクションを処理し、例外をスロー/処理/ロギングする条件を理解してください。これは、Springのトランザクション管理が何をしようとしているのかよく理解する方法です。

なぜ、ログには私のコントローラ(biz.controllers.rest.administrator.OrderController.closeOrder)のみが記載されており、サービスやリポジトリへのリンクはありませんか?

at com.sun.proxy.$Proxy128.closeOrder(Unknown Source) ~[na:na]

(プロキシ経由)OrderServiceのへの呼び出しを表しんあなたのスタックトレース内のこの行

。通常、スタックトレースの実際のクラスは、プロキシインボーカが解決して実際のクラスを呼び出すときに、さらに上にあるはずです。ここで完全なスタックトレースを提供してもよろしいですか?いくつかの行を削除しましたか?ログに他のスタックトレースがあったのでしょうか?

関連する問題