Seven transactional propagation behaviors are defined in the Transactiondefinition interface.
Propagation_required If there is a transaction, the current transaction is supported. If there is no transaction, a new transaction is opened. Default behavior
Propagation_supports If there is a transaction, the current transaction is supported. If there is no transaction, the execution is non-transactional. However, for transaction managers with transactional synchronization, Propagation_supports is slightly different from not using transactions.
Propagation_mandatory if a transaction already exists, the current transaction is supported. Throws an exception if there is no active transaction.
Propagation_requires_new always opens a new transaction. If a transaction already exists, the existing transaction is suspended.
Propagation_not_supported always executes in a non-transactional manner and suspends any existing transactions.
Propagation_never is always non-transactional and throws an exception if there is an active transaction
propagation_nested If an active transaction exists, it is run in a nested transaction. If there is no active transaction, press the Transactiondefinition.propagation_required property to execute
This article focuses on propagation_required,propagation_requires_new, propagation_nested
in practice, there are often cases where servicea calls SERVICEB. And how did the ServiceA and ServiceB's affairs go on in that particular case?
Example 1:
/** Transaction default is required*/
@Transactional
@Service ("UserService")
public class Userserviceimpl implements Userservive {
@Autowired
Private Usermapper Userdao;
@Autowired
Private Commonservice Commonservice;
Public list<userinfo> getusers () {
return Userdao.selectusers ();
}
@Transactional (propagation = propagation.required)
public void Updateuseragebyid (int age, long id) {
Userdao.updateuserinfobyid (age, ID);
Commonservice.updateuserextbyid ("Unknown", 1);
int b = 1/0;
/* Try {
Commonservice.updateuserextbyid ("Unknown", 1);
} catch (Exception e) {
Todo:handle exception
}*/
}
}
//@Transactional
@Service ("Commonservice")
public class Commonserviceimpl implements Commonservice {
@Autowired
Private Usermapper Userdao;
If a run-time exception occurs, this will roll back and throw an exception outside
@Transactional (propagation = propagation.nested)
public void Updateuserextbyid (String address, long ID) {
Userdao.updateuserextbyid (address, id);
int a = 1/0;
}
}
In This example, the Updateuseragebyid transaction in UserService is declared as propagation.required, and the Updateuserextbyid method in Commonservice is called. And this method transaction is declared as propagation.nested. As explained above, Commonservice will run in nested transactions. After testing, when the Updateuserextbyid
When an exception occurs, the rollback operation itself rolls back to the savepoint before it executes. and throws an exception outward, UserService can capture the exception as the case chooses to roll back or not rollback. If no processing occurs, the same data will be rolled back.
Example 2:
@Transactional (propagation = propagation.required)
public void Updateuseragebyid (int age, long id) {
Userdao.updateuserinfobyid (age, ID);
Commonservice.updateuserextbyid ("Unknown", 1);
int b = 1/0;
If a run-time exception occurs, this will roll back and throw an exception outside
@Transactional (propagation = propagation.nested)
public void Updateuserextbyid (String address, long ID) {
Userdao.updateuserextbyid (address, id);
int a = 1/0;
}
exceptions occur in the UserService method because they are nested transactions, so both UserService and Commonservice are rolled back.
Example 3:
@Transactional (propagation = propagation.required)
public void Updateuseragebyid (int age, long id) {
Userdao.updateuserinfobyid (age, ID);
Commonservice.updateuserextbyid ("Unknown", 1);
int b = 1/0;
//If a run-time exception occurs, this will roll back and throw an exception outside
@Transactional (propagation = propagation.requires_new)
public void Updateuserextbyid (String address, long ID) {
Userdao.updateuserextbyid (address, id);
int a = 1/0;
}
The simulation here is that Commonservice is using propagation.requires_new. Transactions in the UserService are suspended. Commonservice will open a new business. After testing, the Commonservice exception is simulated here, and its corresponding transaction is rolled back. Also here will be thrown outside the exception, userservice depending on the situation of exception handling, select Rollback or not rollback.
Example 4:
@Transactional (propagation = propagation.required)
public void Updateuseragebyid (int age, long id) {
Userdao.updateuserinfobyid (age, ID);
Commonservice.updateuserextbyid ("Unknown", 1);
int b = 1/0;
If a run-time exception occurs, this will roll back and throw an exception outside
@Transactional (propagation = propagation.requires_new)
public void Updateuserextbyid (String address, long ID) {
Userdao.updateuserextbyid (address, id);
int a = 1/0;
An exception occurred simulating userservice here. We guessed whether Commonservice would roll back. The result of the experiment is that Commonservice does not roll back. Because before the userservice occurs an exception. Commonservice's transaction has been commit.
Example 5:
@Transactional (propagation = propagation.required)
public void Updateuseragebyid (int age, long id) {
Userdao.updateuserinfobyid (age, ID);
Commonservice.updateuserextbyid ("Unknown", 1);
int b = 1/0;
try {
Commonservice.updateuserextbyid ("Unknown", 1);
} catch (Exception e) {
Todo:handle exception
}
}
@Transactional (propagation = propagation.required)
public void Updateuserextbyid (String address, long ID) {
Userdao.updateuserextbyid (address, id);
int a = 1/0;
}
Finally, let's look at the situation of using propagation.required. This simulates the commonservice exception, without suspecting that Commonservice will definitely roll back. But here UserService the exception is caught, UserService will be rolled back. The answer is no. Because Commonservice does not throw an exception at all. Both use a transaction, Commonservice an exception, and the entire transaction is rollback directly.
Well, it's probably clear how the spring transaction is propagated. There are many communication links on the Internet, but all of them are foggy. So the article is hereby recorded.