New project trial run, DBA prompts the production database a table of transactions 20 minutes are not committed, the analysis process is as follows:
1. Check the logs log file for the last 20 minutes for error logs;
2. Found that a table has an insert error log, the initial judgment is inserted by the table exception, and did not do rollback operation;
3. View Code: The Operation of the table DAO, service, transaction processing for spring declarative transactions, and control to the Service layer;
4. Scene Restore:
Open Spring's debug log (view database conn Open, commit, rollback must have debug enabled)
Simulate inserting exception data
Break point test ....
5. Abnormal log reproduction, analysis log found no transaction processing (the default since the database automatic transaction submission);
6. The cause of the problem is initially determined as follows: Spring declarative transaction agent failure
Code Analysis:
1. Configuration files
Because the transaction is configured on the service layer, look directly at the configuration of the service:
<!--Business Transaction Management Services - <BeanID= "Transactionmanager_masopen"class= "Org.springframework.jdbc.datasource.DataSourceTransactionManager"> < Propertyname= "DataSource"ref= "Datasource_masopen"></ Property> </Bean> <!--"Biz business Logic Layer Service Transaction proxy template-Tx proxy templates" - <BeanID= "Txproxyservice_masopen"class= "Org.springframework.transaction.interceptor.TransactionProxyFactoryBean"Abstract= "true"> < Propertyname= "TransactionManager"ref= "Transactionmanager_masopen" /> < Propertyname= "Proxytargetclass"value= "false" /> < Propertyname= "Transactionattributes"> <Props> <propKey= "get*">Propagation_supports,-throwable,readonly</prop> <propKey= "query*">Propagation_supports,-throwable,readonly</prop> <propKey= "find*">Propagation_supports,-throwable,readonly</prop> <propKey= "count*">Propagation_supports,-throwable,readonly</prop> <propKey= "update*">propagation_required,-throwable,isolation_read_committed</prop> <propKey= "insert*">propagation_required,-throwable,isolation_read_committed</prop> <propKey= "finish*">propagation_required,-throwable,isolation_read_committed</prop> <propKey= "batch*">propagation_required,-throwable,isolation_read_committed</prop> <propKey="*">propagation_required,-throwable,isolation_read_committed</prop> </Props> </ Property> </Bean> <!--transaction Control Definition - <BeanID= "Orderservice_masopen"Parent= "Txproxyservice_masopen"> < Propertyname= "Target"ref= "OrderService"/> </Bean>
Explain:
A. Defines a template txproxyservice_masopen that handles transactions, and any service class that needs to be transacted can use it directly
(Note: The configuration of all classes is different from placing all transactions directly in XX directory)
-throwable is the configuration of the rollback, and is generally configured as-exception
-Indicates that a rollback is required when the exception is thrown
+ means that even if the exception is thrown, the transaction must be committed
Throwable is the parent of all exception, as long as there is an exception rollback
B.orderservice did the proxy class Orderservice_masopen
2. Code
Public Interface OrderService { ... Slightly.... @Service ("OrderService") Public class Implements OrderService { /** * Order database operation DAO */ @Resource Private Orderdao Orderdao_masopen; Slightly....
The OrderService interface is defined, and then Orderserviceimpl implements the interface and sets the resource name=orderservice through the annotation (the bean is the agent class ref above 1)
3.service Interface Call
/** * Order database operation service */ @Resource private OrderService Orderservice_masopen, ..... Slightly.... Logger.info ("Landing log information:" + context.getlogs ()); int [] Flag2 = Logservice_masopen.batchinsertlog (context.getlogs ()); int [] Updateflag = Checkbatchupdateresult (flag2); Logger.info ("Total log records: {}, Update succeeded: {}, update failed: {}", Context.getlogs (). Size (), updateflag[0], updateflag[1]);
Inject the service into other business classes and invoke it in the business logic (typical short transaction)
Here's the problem:
Normal injection of service
@Resource
Private OrderService Orderservice_masopen;
What is the reason for calling the resource without transaction processing???
4. Single-Step commissioning
When the method is called, view the service being proxied and discover objects that are not proxied:
Analysis:
Interface: OrderService
Implementation class: Orderserviceimpl
Proxy class: Orderservice_masopen
Call Injection:
@Resource
Private OrderService Orderservice_masopen;
Obviously, the problem is where the service is injected, the OrderService is automatically injected through resource for its implementation class Orderserviceimpl, not the proxy class Orderservice_ Masopen
First of all:
In spring, 2 beans are declared: implementation class Orderserviceimpl, proxy class Orderservice_masopen
But when injected, only the implementation class is recognized, no proxy class is identified
5. Modification of the scheme
Declares a proxy class in spring to prevent recognition of errors
A. Step one: Remove the annotation that implements class Orderserviceimpl
// @Service ("OrderService")--removing Public class Implements OrderService { ... Slightly....
B. Step two: The configuration file does not use the ref specified Bean, writes the Dead Bean Path directly,
<!--transaction control definition--><bean id= "orderservice_masopen" parent= "Txproxyservice_masopen" > <property name= " Target "> class=" Com.shengpay.masopen.domain.service.impl.OrderServiceImpl "></bean> </property></bean>
Test and view logs to successfully use the proxy class: Pay attention to the marked red $Proxy
6. Summary of Causes
Why does spring declare 2 beans, which are not able to recognize the agent's bean when injected.
The error is on the use of the resource annotaion:
The function of @Resource is equivalent to @autowired, but @autowired is injected automatically by Bytype. @Resource Assembly Order (1). If name and type are specified at the same time, the uniquely matched bean is found from the spring context to assemble, and an exception is thrown if it is not found; (2). If name is specified, a bean matching the name (ID) from the context is assembled, and an exception is thrown if it is not found; (3). If type is specified, an exception is thrown when a unique bean of type matching is found in the context, not found or more than one is found; (4). If neither name is specified and type is not specified, the assembly is automatically byname, and if there is no match, the fallback is a match for the original type and is automatically assembled if matched;
If you still declare two beans, there is still to use resource injection, as long as simply specify the name can be accurately identified as the proxy class, the code is as follows:
/***/@Resource (name= "Orderservice_masopen")private OrderService Orderservice_masopen;
Spring3 declarative transaction transactions cannot roll back rollback analysis (annotation and XML configuration Mix)