Mingling DB transactions and logging from a design perspective

Say we have a view page where users perform actions in multiple steps, some of these actions would involve DB operations with transactions (the snippets are in pseudo-code like from):

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>View 1:
Step 1:
...
Step 2:
...
Call ActionX
Step 3:
...
ActionX: # can be called from different points in the view
...
Begin Transaction
DB ops
End Transaction
</code>
<code>View 1: Step 1: ... Step 2: ... Call ActionX Step 3: ... ActionX: # can be called from different points in the view ... Begin Transaction DB ops End Transaction </code>
View 1:
    Step 1:
        ...

    Step 2:
        ...
        Call ActionX

    Step 3:
        ...    

ActionX: # can be called from different points in the view
    ...
    Begin Transaction
    DB ops
    End Transaction

Say we want to log the user progress in the view (or save some states) in a persistent manner in the DB, so that if the program/app is interrupted we can re-establish the state to the last user action inside a view:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>View1:
Step 1:
...
Logger.log('view1-step1-done')
Step 2:
...
Call ActionX
Logger.log('view1-step2-done')
Step 3:
...
Logger.log('view1-step3-done')
</code>
<code>View1: Step 1: ... Logger.log('view1-step1-done') Step 2: ... Call ActionX Logger.log('view1-step2-done') Step 3: ... Logger.log('view1-step3-done') </code>
View1:
    Step 1:
        ...
        Logger.log('view1-step1-done')

    Step 2:
        ...
        Call ActionX
        Logger.log('view1-step2-done')

    Step 3:
        ...
        Logger.log('view1-step3-done')

Now ideally, we would want to have the persistent logging and the DB based transactional actions to be both done in the same DB transaction, because we don’t want to create an inconsistent state where an action is performed
but is not reflected in the log state, or vice versa.

The question is: how to achieve the said goal with minimum inter-dependency and SOC. Some suggestions for example:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>View 1:
Step 1:
...
Step 2:
...
Begin Transaction
Call ActionX # begin/end transaction statements will be removed from ActionX
Logger.log('view1-step3-done')
End Transaction
Step 3:
...
</code>
<code>View 1: Step 1: ... Step 2: ... Begin Transaction Call ActionX # begin/end transaction statements will be removed from ActionX Logger.log('view1-step3-done') End Transaction Step 3: ... </code>
View 1:
    Step 1:
        ...

    Step 2:
        ...
        Begin Transaction
        Call ActionX    # begin/end transaction statements will be removed from ActionX
        Logger.log('view1-step3-done')
        End Transaction

    Step 3:
        ...

Don’t like this because the handling of transactions belongs naturally in the action itself.

Or, another one:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>View 1:
Step 1:
...
Step 2:
...
Call ActionX (logMsg='view1-step3-done')
Step 3:
...
ActionX (logMsg):
...
Begin Transaction
DB ops
Logger.log(logMsg)
End Transaction
</code>
<code>View 1: Step 1: ... Step 2: ... Call ActionX (logMsg='view1-step3-done') Step 3: ... ActionX (logMsg): ... Begin Transaction DB ops Logger.log(logMsg) End Transaction </code>
View 1:
    Step 1:
        ...

    Step 2:
        ...
        Call ActionX (logMsg='view1-step3-done') 

    Step 3:
        ...

ActionX (logMsg): 
    ...
    Begin Transaction
    DB ops
    Logger.log(logMsg)
    End Transaction

Don’t like this one either. The log message handling doesn’t belong in the actions.

2

The primary guidance for this question is to separate out the responsibilities.

It appears that you are trying to link an Action’s transactional state with the Log’s transactional state, and I think that’s a mistake. Record the Action changes based upon the Action. Record the Log status based upon the resulting (returned) status. If the Action succeeds, then Log a success status message. Likewise, if the Action failed, then Log an error message to that effect.

Since your log messages appear to be indicating status from the Views, then it is the Views’ responsibility to handling the logging.

If the log messages are related to the internal aspects of the Action, then the Action should take the responsibility of logging.

Please keep in mind that those two positions are not exclusive of each other. You might find that you need to log both the Views’ progress as well as internal aspects of the Action. At that point, you would have both areas (Views and Action) making logging calls.

1

A nested transaction would work if your database supports them.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>View 1:
Step 1:
...
Step 2:
...
Begin Transaction
Call ActionX # begin/end transaction statements will be removed from ActionX
Logger.log('view1-step2-done')
End Transaction
Step 3:
...
ActionX ():
...
Begin Transaction
DB ops
End Transaction
</code>
<code>View 1: Step 1: ... Step 2: ... Begin Transaction Call ActionX # begin/end transaction statements will be removed from ActionX Logger.log('view1-step2-done') End Transaction Step 3: ... ActionX (): ... Begin Transaction DB ops End Transaction </code>
View 1:
Step 1:
    ...

Step 2:
    ...
    Begin Transaction
    Call ActionX    # begin/end transaction statements will be removed from ActionX
    Logger.log('view1-step2-done')
    End Transaction

Step 3:
    ...

ActionX (): 
...
Begin Transaction
DB ops
End Transaction

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật