To undertake the spring source sentiment edify-custom node resolution. This section is a simple parsing of transactions
Sample Spring configuration file
Simple transaction configuration, the beginning of the save/delete
method plus the transaction, get/find
the beginning of the set to no transaction read-only mode
<tx:adviceid="Txadvice"transaction-manager="TransactionManager"> <tx:attributes> <tx:methodname="save*"propagation="REQUIRED"/> <tx:methodname="delete*"propagation="REQUIRED"/> <tx:methodname="get*"read-only="true"/> <tx:methodname="find*"read-only="true"/> </tx:attributes> </tx:advice>
Txadvicebeandefinitionparser Parser
tx:advice
Node corresponding to the parser TxAdviceBeanDefinitionParser
, the following for the parser under the detailed interpretation
Instantiating an Object
A direct look at the replication getBeanClass()
method
@Override protectedgetBeanClass(Element element) { return TransactionInterceptor.class; }
That is, TxAdviceBeanDefinitionParser
the parser finally resolves tx:advice
the node as an TransactionInterceptor
object
Common set of properties
Private Static FinalString method_element ="Method";Private Static FinalString Method_name_attribute ="Name";Private Static FinalString attributes_element ="Attributes";Private Static FinalString Timeout_attribute ="Timeout";Private Static FinalString Read_only_attribute ="Read-only";Private Static FinalString Propagation_attribute ="Propagation";Private Static FinalString Isolation_attribute ="Isolation";Private Static FinalString Rollback_for_attribute ="Rollback-for";Private Static FinalString No_rollback_for_attribute ="No-rollback-for";
For the above attributes, we can look at the specific parsing
Doparse ()-Parse Tx:advice node
On the source side
@Override protected void Doparse(element element, ParserContext ParserContext, Beandefinitionbuilder builder) {//Parse the bean ref name corresponding to the Transaction-manager property, and the default name is TransactionManagerBuilder.addpropertyreference("TransactionManager", Txnamespacehandler.Gettransactionmanagername(element));//Parse child node Tx:attributesList<element> txattributes = domutils.Getchildelementsbytagname(element, attributes_element);if(Txattributes.size() >1) {ParserContext.Getreadercontext().Error("element <attributes> is allowed at once inside element <advice>", Element); }Else if(Txattributes.size() ==1) {//Using attributes source.Element attributesourceelement = txattributes.Get(0);//Parse Tx:attribute collectionRootbeandefinition attributesourcedefinition =Parseattributesource(Attributesourceelement, ParserContext); Builder.Addpropertyvalue("Transactionattributesource", attributesourcedefinition); }Else{//Registry parser for parsing annotations @transactionalBuilder.Addpropertyvalue("Transactionattributesource",New rootbeandefinition("Org.springframework.transaction.annotation.AnnotationTransactionAttributeSource")); } }
For @Transactional
the resolution of the method we do not expand here, we first look at the general parseAttributeSource()
method of parsing the tx:attribute
collection, which will be wrapped as an NameMatchTransactionAttributeSource.class
object. The source code is as follows
PrivateRootbeandefinitionParseattributesource(Element Attrele, ParserContext parsercontext) {//Parse Tx:method nodeList<element> methods = Domutils.Getchildelementsbytagname(Attrele, method_element); Managedmap<typedstringvalue, rulebasedtransactionattribute> transactionattributemap =NewManagedmap<typedstringvalue, Rulebasedtransactionattribute> (methods.size()); Transactionattributemap.SetSource(ParserContext.Extractsource(Attrele));// for(Element methodele:methods) {//resolves the Name property, which conforms to Ant-style mode. Packaging into Typedstringvalue objectsString name = Methodele.getattribute(Method_name_attribute); Typedstringvalue Nameholder =New Typedstringvalue(name); Nameholder.SetSource(ParserContext.Extractsource(Methodele));//Parse propagation, isolation, timeout, read-only propertiesRulebasedtransactionattribute attribute =New Rulebasedtransactionattribute(); String propagation = Methodele.getattribute(Propagation_attribute); String isolation = Methodele.getattribute(Isolation_attribute); String timeout = Methodele.getattribute(Timeout_attribute); String readOnly = Methodele.getattribute(Read_only_attribute);if(StringUtils.HasText(propagation)) {attribute.Setpropagationbehaviorname(Rulebasedtransactionattribute.prefix_propagation+ propagation); }if(StringUtils.HasText(isolation)) {attribute.Setisolationlevelname(Rulebasedtransactionattribute.prefix_isolation+ isolation); }if(StringUtils.HasText(timeout)) {Try{attribute.SetTimeout(Integer.parseint(timeout)); }Catch(NumberFormatException ex) {ParserContext.Getreadercontext().Error("Timeout must is an integer value: ["+ Timeout +"]", Methodele); } }if(StringUtils.HasText(readOnly)) {attribute.setreadonly(Boolean.valueOf(Methodele.getattribute(Read_only_attribute))); }//Parse Rollback-for, no-rollback-for propertiesList<rollbackruleattribute> Rollbackrules =NewLinkedlist<rollbackruleattribute> ();if(Methodele.Hasattribute(Rollback_for_attribute)) {String Rollbackforvalue = Methodele.getattribute(Rollback_for_attribute);Addrollbackruleattributesto(Rollbackrules,rollbackforvalue); }if(Methodele.Hasattribute(No_rollback_for_attribute)) {String Norollbackforvalue = Methodele.getattribute(No_rollback_for_attribute);Addnorollbackruleattributesto(Rollbackrules,norollbackforvalue); } attribute.Setrollbackrules(Rollbackrules); Transactionattributemap.put(Nameholder, attribute); }//finally packaged into a Namematchtransactionattributesource object, storing the above configurationRootbeandefinition attributesourcedefinition =New rootbeandefinition(Namematchtransactionattributesource.class); Attributesourcedefinition.SetSource(ParserContext.Extractsource(Attrele)); Attributesourcedefinition.getpropertyvalues().Add("Namemap", Transactionattributemap);returnAttributesourcedefinition; }
The code is very simple, all parsing properties, but still some of the above configuration as a summary of the vernacular
Name supports Ant-style syntax, that is, matching the corresponding method, for example save*
, matching saveUser()/save()
methods
- propagation Transaction propagation mode, corresponding to spring's Transactiondefinition interface class constants
- required corresponding
propagation_required
, Determines the current method to create a transaction if no transaction exists. The default configuration
- required_new corresponds to
propagation_required_new
, and the current method determines if a transaction exists, creates a new transaction, resumes the transaction after the method has finished executing, and creates a new transaction. Let the method run in a new transactional environment. That is, the current method will run under a separate new transaction
- supports corresponds to
propagation_supports
, and if a transaction exists for the current method, join the transaction Instead, the method is executed in a non-transactional state
- not_spported corresponds to
propagation_not_supported
, and the current method is judged if there is a transaction, the transaction is suspended, and when the method finishes executing, Restore the transaction again. That is, the current method does not require transaction support
- mandatory corresponds to
propagation_mandatory
, the current method is determined if there is a transaction, the transaction is joined, and the other cannot create a new transaction, and throws an exception. That is, must be running under a transaction
- never corresponds to
propagation_never
, and the current method is judged to throw an exception if there is a transaction, otherwise normal. That is, must run under non-transactional
- nested corresponding to
propagation_nested
, an embedded transaction.
- isolation transaction isolation level, corresponding to spring's Transactiondefinition interface class constants
- default correspondence
Isolation_default
, without isolation requirements, May cause dirty read/unrepeatable read/phantom read
- read_uncommitted corresponding to the JDBC connection
Transaction_read_uncommitted
, which may cause dirty read/unrepeatable read/phantom READ
- read_ The committed corresponds to the
transaction_read_committed
of the JDBC connection, which may cause unrepeatable read/phantom READ
- reaptable_read corresponds to the JDBC connection
Transaction_repeatable_read
, which may cause Phantom read
-
Serializable corresponds to the transaction_serializable
of the JDBC connection, the safest but most consumable
where about dirty reads , non-repeatable read, magic read
concept see citation 24818397. Another PostScript blogger's understanding of non-repeatable read, Phantom read
Both are the same things that occur in the same transaction, and the same conditions are enforced. But non-repeatable read Cares whether the returned data is consistent, and Phantom read Cares if the number of data bars returned is consistent
Timeout time-out parameter, in S. It is only applied to the transaction propagation mode Required/Required_new
, which defaults to-1
Read-only whether to configure transaction read-only, false by default
The ROLLBACK-FOR exception rollback policy configuration, which is the exception that occurs for rollback, can be configured with multiple exceptions that support ,
separation. Note that the configured exception name here also conforms to Ant-style mode
The no-rollback-for exception does not roll back the policy configuration, that is, what exception does not roll back, you can configure multiple exceptions, support ,
separation. Note that the configured exception name here also conforms to Ant-style mode
Spring source sentiment edify-tx:advice parser