2007年5月25日 星期五
2007年5月18日 星期五
TransactionScopeOption.Suppress
實在看不懂,還在MSDTC更改設定。設定老半天,完全不對。
後來,發現只要在scope 中讀取sql2005 的 database 之 table schema,就會發生上述的錯誤。 原來,讀取table schema 是無法交易的。因此,必須將讀取table schema放在TransactionScopeOption.Suppress 中。
程式大意如下:
using (TrsnsactionScope s1 = new TrsnsactionScope()) { UpdateDBOperation1(); Using (TrsnsactionScope s1 = new TrsnsactionScope(TransactionScopeOption.Suppress)) { ReadTableScheam(); //不要加入交易 } UpdateDBOperation2(); }
MSDTC 的設定
原來,還要設定 MSDTC,才能動。(那要 System.Transactions 幹嘛?)
我的測試環境,是APServer, DBServer。程式當然是寫在APServer。
設定過程如下:
首先,要看看Distribute Transaction Coordinator服務是否啟動。請到services.msc 中檢查。
注意,APServer 與DBServer 都要啟動。
再來,到DBServer
1. 使用元件服務,在左方的樹,找到「我的電腦」後,於其上按右鍵,執行「內容」
2. 選"MSDTC" 頁
3. 點擊"Security Configuration"(安全設定)
4. 確定有勾選"Network DTC Access", "Allow Remote Client","Allow Inbound","No authentication"
5. 按確定後,服務會重啟
6. 不過,之前有經驗,伺服器要重新啟重才有用。
再到 APServer,做與上1-3相同的步驟
4 確定有勾選"Network DTC Access", "Allow Inbound/Outbound","No authentication"
5 必要時,重新開機
Transactions 的種類
1 Local transactions in database (eg: SQL server) 2 Local transactions through DB API (eg: ADO.NET) 3 Distributed transactions through Distributed Transaction Coordinator (DTC) 4 Distributed transactions on component level through COM+ (uses DTC) Enterprise Services in the Microsoft .NET Framework 5 Local distributed transactions in ASP.NET and ASMX 6 Microsoft Host Integration Server (HIS) and COM Transactio Integrator for CICS and IMS (COMTI)
2007年5月17日 星期四
http://asp.net/downloads/futures/
2007年5月15日 星期二
思考的方式
一個教授對他的三個博士班學生說:我們要到高山另一頭的村子買瓶醬油。
第一個學生乖乖地爬了一個月的山,終於把醬油買回來;
第二個學生花了數年研發挖山洞專用的TDM潛盾機,並發表三篇Paper拿到博士學位;
第三個學生則跑到兩條街外的7-11,五分鐘就把醬油買回來了。
你會是哪一個呢?
我想想,我大概會是第二個吧!專案常常會Delay不是沒原因的
教授像是專案經理,製訂策略,卻未必都是對的。
第一個學生是乖乖聽話型,把任務當指令,一成不變的「運算」下去。公司需要這些「機器」人,但也容易替換這些機器人。
第二種是創意研發型。雖然重要,卻容易在專案進行時delay 時程。專案進行時,不要再搞創意了。
第三種是「挑戰」型的思考方式。當接受到任務時,會先想一想有沒有更好、更簡易的方法來完成。
重要的思考的方式。
2007年5月14日 星期一
Performance tuning 的簡化步驟
2007年5月11日 星期五
Custom Channel
只能以 SVCUtil 或使用VS2005 來產生 proxy file 嗎?
這樣對開發是一個很痛苦的折磨。
在Client side,通常也會使用與 Server side 相同的 business entity。對於同一個開發平台來說,這是非常重要的事情。
但如果使用 svcutil 來產生 proxy class,就會重複的產生 client side 的 business entity。非常不道德。
經過微軟的Patrick 的努力,幫我找到了使用 Custom Channel 的方法。而且,可以直接 reference 與server side 相同的 service contract, business entity。這對於開發來說,至為重要。
其實 code 相當簡單。
// Business entity: Server side, Client side 共用
[DataContract]
public class Customer
{
public Customer(int customId, string name)
{
this.customId = customId;
this.name = name;
}
private string name;
[DataMember]
public string Name
{
get { return name; }
set { name = value; }
}
private int customId;
[DataMember]
public int CustomId
{
get { return customId; }
set { customId = value; }
}
}
//Business Component: Server side
public class CustomBC
{
public Customer GetFirstCustomer()
{
Customer c = new Customer(1, "Charles");
return c;
}
}
//Contract interface: Server side, client side 共用
[ServiceContract]
public interface ICustomerService
{
[OperationContract]
Customer GetFirstCustomer();
}
//Contract Implementation: Server side
[ServiceBehavior(Name = "CustomerService", Namespace = "http://TestCustomChannel.ServiceContracts/2007/05")]
public class MathService : TestCustomChannel.ServiceContracts.ICustomerService
{
public TestCustomChannel.BusinessEntities.Customer GetFirstCustomer()
{
CustomBC bc = new CustomBC();
return bc.GetFirstCustomer();
}
}
//Client Side: 引用Contract interface, business entity
ICustomerService proxy = new ChannelFactory< ICustomerService >("BasicHttpBinding_ICustomerService").CreateChannel();
Customer c = proxy.GetFirstCustomer();
//Client Side config
<client>
<endpoint address="http://localhost:4122/TestCustomChannel.Host/CustomerService.svc"
binding="basicHttpBinding"
contract="TestCustomChannel.ServiceContracts.ICustomerService"
name="BasicHttpBinding_ICustomerService"
/>
</client>
Length of text, ntext, or image data to be replicated exceeds configured maximum 65536
2007年5月10日 星期四
檢查誰在呼叫我
當assembly發佈出去之後,會被誰呼叫,真的是不知道。
有時,需要確定只能被自己的程式所呼叫。可以利用檢查stackTrace的方法,得知誰在呼叫
public void WhoIsCallingMe()
{
string allowPublicKeyToken = "12345567890abcdefg";
System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace();
//取得呼叫者的FullName
string caller = st.GetFrame(1).GetMethod().ReflectedType.Assembly.FullName;
System.Text.RegularExpressions.Match m = Regex.Match(caller, "PublicKeyToken=(.{16})");
if ((!m.Success) || (!m.Groups[1].Value.Equals(allowPublicKeyToken)))
throw new System.Security.SecurityException("未知的caller");
}